我有以下问题:
给出以下示例数据集:
structure(list(idpat = c("1", "2", "2", "1", "1"), idA = c("100a",
"100b", "100c", "100b", "100a"), redA = c(1, 0, 1, 0, 1), idB = c("200a",
"200b", "200a", "200b", "200a"), redB = c(0, 1, 1, 1, 0)), class = "data.frame", row.names = c(NA,
-5L))
idpat idA redA idB redB
1 1 100a 1 200a 0
2 2 100b 0 200b 1
3 2 100c 1 200a 1
4 1 100b 0 200b 1
5 1 100a 1 200a 0
我想获得:
structure(list(idpat = c(1, 1, 2, 2, 2, 2, 1, 1, 1, 1), id = c("100a",
"200a", "100b", "200b", "100c", "200a", "100b", "200b", "100a",
"200a"), red = c(1, 0, 0, 1, 1, 1, 0, 1, 1, 0)), class = "data.frame", row.names = c(NA,
-10L))
idpat id red
1 1 100a 1
2 1 200a 0
3 2 100b 0
4 2 200b 1
5 2 100c 1
6 2 200a 1
7 1 100b 0
8 1 200b 1
9 1 100a 1
10 1 200a 0
我正在尝试以下操作,但无法得到我所需要的。这个pivot_longer对我来说有点棘手:
df1|>pivot_longer(cols =c("idpat","idA","idB"),names_to = c("id") ,values_to = "vals")
为了完整性,采用
data.table
方法
library(data.table)
melt(setDT(mydata), measure.vars = patterns(id = "^id[AB]", red = "^red[AB]"))
# idpat variable id red
# 1: 1 1 100a 1
# 2: 2 1 100b 0
# 3: 2 1 100c 1
# 4: 1 1 100b 0
# 5: 1 1 100a 1
# 6: 1 2 200a 0
# 7: 2 2 200b 1
# 8: 2 2 200a 1
# 9: 1 2 200b 1
#10: 1 2 200a 0
您可以使用
names_pattern
参数和针对多个值列的特殊 ".value"
来实现您想要的结果,如下所示:
df1 |>
tidyr::pivot_longer(
cols = -idpat,
names_to = c(".value", "what"),
names_pattern = "^(.*?)(.)$"
)
#> # A tibble: 10 × 4
#> idpat what id red
#> <chr> <chr> <chr> <dbl>
#> 1 1 A 100a 1
#> 2 1 B 200a 0
#> 3 2 A 100b 0
#> 4 2 B 200b 1
#> 5 2 A 100c 1
#> 6 2 B 200a 1
#> 7 1 A 100b 0
#> 8 1 B 200b 1
#> 9 1 A 100a 1
#> 10 1 B 200a 0
这是一个基本解决方案。首先创建列表
L
,它定义哪些输入列与哪些输出列关联。我们使用输入列号,但也可以使用相应的输入列名称。
L <- list(idpat = c(1, 1), id = c(2, 4), red = c(3, 5))
data.frame(lapply(L, function(x) c(t(df1[x]))))
## idpat id red
## 1 1 100a 1
## 2 1 200a 0
## 3 2 100b 0
## 4 2 200b 1
## 5 2 100c 1
## 6 2 200a 1
## 7 1 100b 0
## 8 1 200b 1
## 9 1 100a 1
## 10 1 200a 0