如果数据集不是很大(即数百万/数十亿行),我们可以使用apply 和MARGIN=1 循环遍历行,使用逻辑vector 作为向量的子集names index 和paste 他们在一起。在一行中编写代码更容易。
df$Result <- apply(df, 1, FUN = function(x) paste(names(x)[x], collapse=" / "))
但是,如果我们有一个大数据集,另一种选择是创建一个键/值对并通过匹配替换值,它比上述解决方案更快。
v1 <- do.call(paste, df)
unname(setNames(c("A / B", "B", "A", NA), do.call(paste,
expand.grid(rep(list(c(TRUE, FALSE)), 2))))[v1])
#[1] "A / B" "B" NA
或者我们可以使用算术运算来做到这一点
c(NA, "A", "B", "A / B")[1 + df[,1] + 2 * df[,2]]
#[1] "A / B" "B" NA
基准测试
使用@DavidArenburg 的数据集并包括此处发布的两个解决方案(将“df”的列名更改为“A”和“B”)
newPaste <- function(df) {
v1 <- do.call(paste, df)
unname(setNames(c("A / B", "B", "A", NA), do.call(paste,
expand.grid(rep(list(c(TRUE, FALSE)), 2))))[v1])
}
arith <- function(df){
c(NA, "A", "B", "A / B")[1 + df[,1] + 2 * df[,2]]
}
microbenchmark::microbenchmark(Rowwise(df), Colwise(df), newPaste(df),arith(df))
#Unit: milliseconds
# expr min lq mean median uq max neval
# Rowwise(df) 398.024791 453.68129 488.07312 481.051431 523.466771 688.36084 100
# Colwise(df) 25.361609 28.10300 34.20972 30.952365 35.885061 95.92575 100
# newPaste(df) 65.777304 69.07432 82.08602 71.606890 82.232980 176.66516 100
# arith(df) 1.790622 1.88339 4.74913 2.027674 4.753279 58.50942 100