首页 > 解决方案 > 使用变量列表时如何使用或应该使用 case_when 来更改值

问题描述

我相信我想做的事情相对简单,我只是似乎不知道正确的术语来回答我的问题。我有一个包含 9 个变量的数据框。我想创建一个基于另一列变量的新变量。简单的例子:

my.df <- data.frame(col1 = sample(c(1,2), 10, replace = TRUE),
        col2 = as.factor(sample(10)), col3 = letters[1:10],
        col4 = sample(c(TRUE, FALSE), 10, replace = TRUE))


    col1 col2 col3  col4
1     2    8    a  TRUE
2     1    3    b FALSE
3     2    4    c FALSE
4     2    2    d  TRUE
5     2    7    e FALSE
6     2    9    f  TRUE
7     2   10    g FALSE
8     2    6    h FALSE
9     1    1    i FALSE
10    2    5    j FALSE

我想通过使用来自 col3 的信息来创建 col5。我期待这样的事情:

my.df<-my.df %>%
  mutate(col5 = case_when(col3 = c("a", "b", "c") ~"green",
                          col3 = c("g", "h", "i", "j")~"red",
                          col3 = c("d", "e", "f")~"purple"))

我期待这样的结果:

 col1 col2 col3  col4    col5
1     2    8    a  TRUE  green
2     1    3    b FALSE  green
3     2    4    c FALSE  green
4     2    2    d  TRUE  purple
5     2    7    e FALSE  purple
6     2    9    f  TRUE  purple
7     2   10    g FALSE  red
8     2    6    h FALSE  red
9     1    1    i FALSE  red
10    2    5    j FALSE  red

错误必须是逻辑向量,而不是字符向量。如果我更改 (col3 == c("")... 使用 == 我会收到警告消息和问题,即较长的对象长度不是较短对象长度的倍数。

我的解决方案最终是创建一个仅包含名称的向量,然后使用 %in%。但是,我真的认为应该有一个简单的方法来做到这一点?或者可能使用不同的命令,我不必逐行更改值。

我开始工作的例子,我必须为每种颜色做:

grn<-c("a", "b", "c")
my.df<-my.df %>%
      mutate(col5 = case_when(col3 %in% grn~"green")

标签: rlistselectioncase-when

解决方案


也许这有帮助

library(dplyr)
library(stringr)
my.df %>%
    group_by(grp = cumsum(col4)) %>%
    mutate(col5 = setNames(c('green', 'red', 'purple'), 
       c('abc', 'ghij', 'def'))[str_c(col3, collapse='')]) %>%
    ungroup %>% 
    select(-grp)

-输出

# A tibble: 10 x 5
    col1  col2 col3  col4  col5  
   <int> <int> <chr> <lgl> <chr> 
 1     2     8 a     TRUE  green 
 2     1     3 b     FALSE green 
 3     2     4 c     FALSE green 
 4     2     2 d     TRUE  purple
 5     2     7 e     FALSE purple
 6     2     9 f     FALSE purple
 7     2    10 g     TRUE  red   
 8     2     6 h     FALSE red   
 9     1     1 i     FALSE red   
10     2     5 j     FALSE red   

数据

my.df <- structure(list(col1 = c(2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L
), col2 = c(8L, 3L, 4L, 2L, 7L, 9L, 10L, 6L, 1L, 5L), col3 = c("a", 
"b", "c", "d", "e", "f", "g", "h", "i", "j"), col4 = c(TRUE, 
FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)),
row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10"), class = "data.frame")

推荐阅读