以下是一个示例数据。
testdata <- data.frame(A = c(1,0,1,1,0,0),
B = c(2,0,0,0,0,1),
D0 = c("A","A","B","C","A","A"),
D1 = c("B","C","C","A","B","B"),
D2 = c("C", NA,NA,NA,NA,NA),
stringsAsFactors = F)
我想要做的是根据列A
和B
制作一个新列(例如,列Aprime
和Bprime
)。将放置在新列中的值将是
来自D
的列(例如D0, D1, and D2
)。列A
和B
中的值告诉我选择哪个D
列。例如,对于新列Aprime
,第一列
值为"B"
,因为A
的第一行为1,因此它应该占据D1
列的第一行。对于Bprime的第一行,它应该有"C"
,因为
第一个B
为2,因此它应该采用第一个D2
值。结果应该是这样的:
A B D0 D1 D2 Aprime Bprime
1 1 2 A B C B C
2 0 0 A C <NA> A A
3 1 0 B C <NA> C B
4 1 0 C A <NA> A C
5 0 0 A B <NA> A A
6 0 1 A B <NA> A B
我使用下面的ifelse语句来得出上述结果:
testdata$Aprime <- ifelse(testdata$A == 0, testdata$D0, ifelse(testdata$A == 1, testdata$D1, testdata$D2))
testdata$Bprime <- ifelse(testdata$B == 0, testdata$D0, ifelse(testdata$B == 1, testdata$D1, testdata$D2))
但是,我想要更通用的一个,因为D列不是固定的(例如,可以有D3到D20)。 如果没有为大于0的Ds写一个ifelse(即,D1等等),我怎么能这样做呢?
TIA。
答案 0 :(得分:3)
这是一个基本R方法,使用矩阵子集来选择值,lapply
循环遍历A和B列。
testdata[c("aprime", "bprime")] <-
lapply(testdata[c("A", "B")],
function(x) testdata[, 3:5][cbind(seq_len(nrow(testdata)), x + 1)])
左侧提供新变量的名称。在右边,lapply的第一个参数提供了要运行的变量集。 lapply
的第二个参数,testdata[, 3:5][cbind(seq_len(nrow(testdata)), x + 1)]
首先将data.frame子集化到索引列(D0-D2)中,然后使用cbind
提供用于子集化的矩阵。使用seq_len..nrow
选择行索引,并从lapply
的第一个参数中提供的变量中选择列。
返回
testdata
A B D0 D1 D2 aprime bprime
1 1 2 A B C B C
2 0 0 A C <NA> A A
3 1 0 B C <NA> C B
4 1 0 C A <NA> A C
5 0 0 A B <NA> A A
6 0 1 A B <NA> A B
有关矩阵子集的更多信息,请查看?"["
。