使用dplyr大小写时将值赋给向量

时间:2017-10-09 13:49:26

标签: r dplyr

我想将vales分配给命名向量,具体取决于我通过行循环的df中的值。我根据文档看到案例的RHS是一个向量,而我试图做的是让RHS成为一个实际的分配步骤。这可能吗? Case_when在这里比使用if语句更优雅:

test.df <- data.frame(cat1 = c('label1', 'label2', 'label3'), 
                  cat2 = c('label3', '', ''),
                  cat3 = c('', 'label2', 'label1'))

test.lst <- apply(test.df, 1, function(x){
                test.vec <- c(label1 = 0, label2 = 0, label3 = 0)

                case_when(
                  x[['cat1']]=='label1' | x[['cat2']]=='label1' | x[['cat3']]=='label1' ~ test.vec['label1'] <- 1,
                  x[['cat1']]=='label2' | x[['cat2']]=='label2' | x[['cat3']]=='label2' ~ test.vec['label2'] <- 1,
                  x[['cat1']]=='label3' | x[['cat2']]=='label3' | x[['cat3']]=='label3' ~ test.vec['label3'] <- 1
                )
              })

2 个答案:

答案 0 :(得分:4)

您可以使用local:CustomizableTreeBaseItem包中的transmute函数仅保留在函数调用中创建/修改的列。因此,您可以创建一个全新的数据帧。它看起来像这样:

dplyr

,您的输出将如下所示:

test.lst <- test.df %>% 
  transmute(label1 = case_when(
    cat1 == "label1" | cat2 == "label1" | cat3 == "label1" ~ 1,
    TRUE ~ 0
  ),
  label2 = case_when(
    cat1 == "label2" | cat2 == "label2" | cat3 == "label2" ~ 1,
    TRUE ~ 0
  ),
  labels3 = case_when(
    cat1 == "label3" | cat2 == "label3" | cat3 == "label3" ~ 1,
    TRUE ~ 0
  ))

注意, label1 label2 labels3 1 1 0 1 2 0 1 0 3 1 0 1 包及其大部分功能都是矢量化的。因此,他们已经对每一行执行了所需的操作,而无需dplyr循环或for / apply函数。这样可以加快代码速度并使其更具可读性。

答案 1 :(得分:0)

case_when不是必需的,这是另一种解决方案:

sapply(paste0('label', 1:3), function(x) sign(rowSums(as.matrix(test.df) == x)) )
#      label1 label2 label3
# [1,]      1      0      1
# [2,]      0      1      0
# [3,]      1      0      1