如何使用现有列中的值创建新列,以告知新值将来自哪一列?

时间:2017-05-21 12:21:15

标签: r dataframe

以下是一个示例数据。

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)

我想要做的是根据列AB制作一个新列(例如,列AprimeBprime)。将放置在新列中的值将是 来自D的列(例如D0, D1, and D2)。列AB中的值告诉我选择哪个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。

1 个答案:

答案 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

有关矩阵子集的更多信息,请查看?"["