在数据框上按行应用函数,与列数无关

vct*_*trd 3 r dataframe dplyr

我想在data.frame上按行应用函数,以根据行中的值连接列标题.

df 
      A     B
1  TRUE  TRUE
2 FALSE  TRUE
3 FALSE FALSE

      A     B Result
1  TRUE  TRUE A / B
2 FALSE  TRUE   B
3 FALSE FALSE NA
Run Code Online (Sandbox Code Playgroud)

我读了关于使用mutate()和rowwise()的dplyr,但我不知道如何应用它们,因为列不是常量.

对于一行"我"我会做类似的事情:

paste(names(df)[as.logical(df[i,])], collapse = ' / ')
Run Code Online (Sandbox Code Playgroud)

欢迎任何帮助.

谢谢.

Dav*_*urg 6

我建议不要apply在data.frames上使用(由于矩阵转换),特别是边距为1(R中的行操作很慢).相反,您可以非常轻松地在列上进行矢量化而无需矩阵转换,这是一个示例

res <- rep(NA_character_, nrow(df))
for(j in names(df)) res[df[[j]]] <- paste(res[df[[j]]], j, sep = " / ")
sub("NA / ", "", res, fixed = TRUE)
# [1] "A / B" "B"     NA   
Run Code Online (Sandbox Code Playgroud)

以下是显示约X16改善的基准

set.seed(123)
N <- 1e5
df <- as.data.frame(matrix(sample(c(TRUE, FALSE), N*2, replace = TRUE), ncol = 2))

Rowwise <- function(df) apply(df, 1, FUN = function(x) paste(names(x)[x], collapse=" / "))

Colwise <- function(df) {
  res <- rep(NA_character_, nrow(df));
  for(j in names(df)) res[df[[j]]] <- paste(res[df[[j]]], j, sep = " / ");
  sub("NA / ", "", res, fixed = TRUE)
} 

microbenchmark::microbenchmark(Rowwise(df), Colwise(df))
# Unit: milliseconds
#        expr       min        lq      mean    median        uq      max neval cld
# Rowwise(df) 458.54526 502.43496 545.47028 548.42042 584.18000 669.6161   100   b
# Colwise(df)  27.11235  27.83873  34.65596  29.05341  32.83664 137.7905   100  a 
Run Code Online (Sandbox Code Playgroud)