【问题标题】:Using case_when, how to mutate a new list-column that nests a vector within?使用 case_when,如何改变嵌套向量的新列表列?
【发布时间】:2021-04-21 21:57:49
【问题描述】:

我正在尝试使用dplyrcase_when() 根据其他列中的条件来改变新列。但是,我希望新列嵌套一个向量。

示例

考虑以下玩具数据。在此基础上,我想总结一下英国的地理版图。

library(tibble)

set.seed(1)
my_mat <- matrix(sample(c(TRUE, FALSE), size = 40, replace = TRUE), nrow = 10, ncol = 4) 
colnames(my_mat) <- c("England", "Wales", "Scotland", "Northern_Ireland")
my_df <- as_tibble(my_mat)

> my_df

## # A tibble: 10 x 4
##    England Wales Scotland Northern_Ireland
##    <lgl>   <lgl> <lgl>    <lgl>           
##  1 TRUE    TRUE  TRUE     FALSE           
##  2 FALSE   TRUE  TRUE     FALSE           
##  3 TRUE    TRUE  TRUE     TRUE            
##  4 TRUE    TRUE  TRUE     FALSE           
##  5 FALSE   TRUE  TRUE     TRUE            
##  6 TRUE    FALSE TRUE     TRUE            
##  7 TRUE    FALSE FALSE    FALSE           
##  8 TRUE    FALSE TRUE     TRUE            
##  9 FALSE   FALSE TRUE     FALSE           
## 10 FALSE   TRUE  FALSE    FALSE  

我想改变一个新的collective_geo_territory 列。

  1. 如果EnglandScotlandWalesNorthern_Ireland都是TRUE,那么我们说这是United_Kingdom
  2. 否则,如果只有EnglandScotlandWalesTRUE,那么我们说这是Great_Britain
  3. 任何其他组合都只会返回一个带有TRUE 国家名称的向量。

我的尝试

到目前为止,我知道如何使用以下代码解决上面详述的条件 (1)(2)

library(dplyr)

my_df %>%
  mutate(collective_geo_territory = case_when(England == TRUE & Wales == TRUE & Scotland == TRUE & Northern_Ireland == TRUE ~ "United_Kingdom",
                                              England == TRUE & Wales == TRUE & Scotland == TRUE ~ "Great_Britain"))

期望的输出

但是,我想通过collective_geo_territory 列实现如下所示的输出:

## # A tibble: 10 x 5
##      England Wales Scotland Northern_Ireland collective_geo_territory
##      <lgl>   <lgl> <lgl>    <lgl>            <list>                   
##   1  TRUE    TRUE  TRUE     FALSE            <chr [1]>   # c("Great_Britain")           
##   2  FALSE   TRUE  TRUE     FALSE            <chr [2]>   # c("Wales", "Scotland")                      
##   3  TRUE    TRUE  TRUE     TRUE             <chr [1]>   # c("United_Kingdom")        
##   4  TRUE    TRUE  TRUE     FALSE            <chr [1]>   # c("Great_Britain")
##   5  FALSE   TRUE  TRUE     TRUE             <chr [3]>   # c("Wales", "Scotland", "Northern_Ireland")
##   6  TRUE    FALSE TRUE     TRUE             <chr [3]>   # c("England", "Scotland", "Northern_Ireland")
##   7  TRUE    FALSE FALSE    FALSE            <chr [1]>   # c("England") 
##   8  TRUE    FALSE TRUE     TRUE             <chr [3]>   # c("England", "Scotland", "Northern_Ireland")
##   9  FALSE   FALSE TRUE     FALSE            <chr [1]>   # c("Scotland") 
##   10 FALSE   TRUE  FALSE    FALSE            <chr [1]>   # c("Wales") 

【问题讨论】:

    标签: r dplyr tibble


    【解决方案1】:

    这是一种方法:

    library(purrr) # used for pmap
    
    my_df %>%
      mutate(collective_geo_territory = case_when(
        England & Wales & Scotland & Northern_Ireland ~ list("United_Kingdom"),
        England & Wales & Scotland ~ list("Great_Britain"),
        TRUE ~ pmap(my_df, ~names(my_df)[c(...)]))
        )
    

    基本上,最后一行的工作方式如下:

    1. 左侧可以简单地为TRUE,因为case_when() 终止于第一个相关的TRUE。所以,只有条件 1 和 2 都失败了,我们才会到达这条线。
    2. 右侧基本上是说遍历我的数据集的行 (pmap) 并应用以下函数:获取我的数据集中的列的名称 (names) 并将它们子集 ([])仅适用于那些值为真的人(包含在c()中)

    一些补充说明:

    1. 请注意,我还必须将前两个条件的右侧幻灯片(例如 "United_Kingdom")包裹在 list() 中,因为 case_when() 要求结果向量的类型一致
    2. 我将多余的England == TRUE(其他国家也一样)简单地更改为England。由于这些列已经包含逻辑值,因此无需重新检查它们的值,这使代码更具可读性。

    【讨论】:

      猜你喜欢
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      相关资源
      最近更新 更多