【问题标题】:Multiple patterns matching with a column by dplyrdplyr 与一列匹配的多个模式
【发布时间】:2021-12-30 23:06:01
【问题描述】:

我想创建一个从字符类型的列派生的列。我有一些模式,可以接受,其他的不应该接受。

这是我尝试过的:

library(dplyr)

set.seed(1)

index <- sample(1:nrow(iris),10)

iris2 <- iris[index,]

required_cols <- c('ersicol','inic')

iris2 %>% 
mutate(logical_column = case_when(any(sapply(required_cols,grepl,x = Species)) ~ 'WORKED',
                                  TRUE ~ 'NOT_WORKED'))

在这种情况下,所有logical_column 都标记为“已工作”,但只有“ersicol”或“inic”模式(包括观察结果)应标记为“已工作”。

想要的输出应该是这样的:

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species    logical_column
          <dbl>       <dbl>        <dbl>       <dbl> <fct>      <chr>         
 1          5.8         2.7          4.1         1   versicolor WORKED        
 2          6.4         2.8          5.6         2.1 virginica  WORKED        
 3          4.4         3.2          1.3         0.2 setosa     NOT_WORKED        
 4          4.3         3            1.1         0.1 setosa     NOT_WORKED        
 5          7           3.2          4.7         1.4 versicolor WORKED        
 6          5.4         3            4.5         1.5 versicolor WORKED        
 7          5.4         3.4          1.7         0.2 setosa     NOT_WORKED        
 8          7.6         3            6.6         2.1 virginica  WORKED        
 9          6.1         2.8          4.7         1.2 versicolor WORKED        
10          4.6         3.4          1.4         0.3 setosa     NOT_WORKED    

提前致谢。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    any 是这里的关键。它只是从完整数据中获取,如果我们想使用 OP 的代码,请使用 rowwise

    library(dplyr)
    iris2 %>%
        rowwise %>%
        mutate(logical_column = case_when(any(sapply(required_cols,
               grepl,x = Species)) 
             ~ 'WORKED',
        
                                      TRUE ~ 'NOT_WORKED')) %>%
        ungroup
    

    -输出

    # A tibble: 10 × 6
       Sepal.Length Sepal.Width Petal.Length Petal.Width Species    logical_column
              <dbl>       <dbl>        <dbl>       <dbl> <fct>      <chr>         
     1          5.8         2.7          4.1         1   versicolor WORKED        
     2          6.4         2.8          5.6         2.1 virginica  WORKED        
     3          4.4         3.2          1.3         0.2 setosa     NOT_WORKED    
     4          4.3         3            1.1         0.1 setosa     NOT_WORKED    
     5          7           3.2          4.7         1.4 versicolor WORKED        
     6          5.4         3            4.5         1.5 versicolor WORKED        
     7          5.4         3.4          1.7         0.2 setosa     NOT_WORKED    
     8          7.6         3            6.6         2.1 virginica  WORKED        
     9          6.1         2.8          4.7         1.2 versicolor WORKED        
    10          4.6         3.4          1.4         0.3 setosa     NOT_WORKED  
    

    如果我们使用矢量化选项可能会更有效 - paste (str_c) 'required_cols' 到单个字符串 (collapse = "|"),使用 str_detect 检查子字符串是否存在,将其转换为数字索引 (+1) 并使用索引替换 vector

    library(stringr)
    iris2 %>% 
       mutate(logical_column = c("NOT_WORKED", "WORKED")[
         1 + str_detect(Species, str_c(required_cols, collapse = "|"))])
    

    -输出

      Sepal.Length Sepal.Width Petal.Length Petal.Width    Species logical_column
    68           5.8         2.7          4.1         1.0 versicolor         WORKED
    129          6.4         2.8          5.6         2.1  virginica         WORKED
    43           4.4         3.2          1.3         0.2     setosa     NOT_WORKED
    14           4.3         3.0          1.1         0.1     setosa     NOT_WORKED
    51           7.0         3.2          4.7         1.4 versicolor         WORKED
    85           5.4         3.0          4.5         1.5 versicolor         WORKED
    21           5.4         3.4          1.7         0.2     setosa     NOT_WORKED
    106          7.6         3.0          6.6         2.1  virginica         WORKED
    74           6.1         2.8          4.7         1.2 versicolor         WORKED
    7            4.6         3.4          1.4         0.3     setosa     NOT_WORKED
    

    【讨论】:

    • 感谢@akrun。我也想问一下,如何在 data.table 中实现它?我认为那里没有按行模式。
    • @SametSökel 你可以使用setDT(iris2)[, yourfunction,by = 1:nrow(iris2)]
    猜你喜欢
    • 1970-01-01
    • 2016-04-24
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 2012-03-21
    • 2011-10-20
    相关资源
    最近更新 更多