在下面的dataframe中,我希望创建一个名为D2的新列,它与对应的A、B或C列匹配。例如,如果D == A,我想要D2 == A2。
A   A2  B   B2  C   C2  D
1   10  2   90  3   9   1
1   11  2   99  3   15  1
1   42  2   2   3   9   2
1   5   2   54  3   235 2
1   13  2   20  3   10  3
1   6   2   1   3   4   3这就是我希望新的数据框架看起来的样子:
A   A2  B   B2  C   C2  D   D2
1   10  2   90  3   9   1   10
1   11  2   99  3   15  1   11
1   42  2   2   3   9   2   2
1   5   2   54  3   235 2   54
1   13  2   20  3   10  3   10
1   6   2   1   3   4   3   4我已经成功地使用dplyr使用ifelse语句完成了这一任务,但是由于我使用了许多列,过了一段时间,它变得乏味起来。我想知道是否有更聪明的方法来完成同样的任务。
library(dplyr)  
newdata <- olddata %>% mutate(D2=ifelse(D==A,A2,ifelse(D==B,B2,C2)))发布于 2016-08-05 03:08:16
我们可以使用来自max.col的base R高效地完成这一任务。只包含'A‘、'B’、'C‘列('d1')的'olddata’子集,检查它是否等于'D‘(在复制'D’以匹配长度之后),使用max.col查找最大元素的索引(在本例中为真,假设每行有一个真值),乘以2作为'A1‘、'B2’、'C2‘列在'A’、'B‘、'C’之后交替。cbind与行序列一起创建行/列索引,并在此基础上提取元素以创建“D2”列。
d1 <- olddata[c("A", "B", "C")]
olddata$D2 <- olddata[cbind(1:nrow(d1), max.col(d1 == rep(olddata["D"], 
          ncol(d1)), "first")*2)]
olddata$D2
#[1] 10 11  2 54 10  4一种稍微不同的方法是使用lapply单独比较循环中的列(如果数据集非常大,转换为大逻辑matrix可能会花费内存),并且基于此,我们将A2、B2、C2的相应列与mapply进行子集。
i1 <- grep("^[^D]", names(olddata)) #create an index for columns that are not D
i2 <- seq(1, ncol(olddata[i1]), by = 2)#for subsetting A, B, C
i3 <- seq(2, ncol(olddata[i1]), by = 2)# for subsetting A2, B2, C2
olddata$D2 <- c(mapply(`[`, olddata[i3], lapply(olddata[i2], `==`, olddata$D)))
olddata$D2
[1] 10 11  2 54 10  4https://stackoverflow.com/questions/38780274
复制相似问题