【问题标题】:Dplyr case_when programmatically comparing cases and conditions in different dataframesDplyr case_when 以编程方式比较不同数据帧中的案例和条件
【发布时间】:2021-06-02 12:22:05
【问题描述】:

所以,我有一些学生写了一份谷歌表格调查。调查采用字符串形式,他们在其中选择一个下拉菜单,其中包含以下选项:

我不觉得难过
有时我会感到难过
我经常感到难过
总觉得难过

这是一种仿照贝克抑郁量表的问题。每个项目分别与一个 0,1,2,3 相关联。

其中有大约 20 个变量。

所以,我有 2 个数据框。

df1 有调查数据(回复字符串)。这是其中的 2 个变量

    head(df1[1:7,c('sad','optimism')])
    sad                                       optimism                                
     <chr>                                     <chr>                                   
    1 Throughout the day I sometimes feel sad   I am somewhat optimistic about my future
    2 Throughout the day I sometimes feel sad   I am somewhat optimistic about my future
    3 Throughout the day I sometimes feel happy I feel discouraged about the future     
    4 Throughout the day I sometimes feel happy I am optimistic about my future         
    5 Throughout the day I sometimes feel happy I am somewhat optimistic about my future
    6 Throughout the day I sometimes feel happy I am somewhat optimistic about my future
    7 Throughout the day I sometimes feel happy I feel discouraged about the future   

df2 有一个条件键

    head(df2[1:4,c('sad','optimism')])
     sad                                   optimism                                              
      <chr>                                 <chr>                                                 
    1 Throughout the day I feel happy       I am optimistic about my future                       
    2 Throughout the day I sometimes feel … I am somewhat optimistic about my future              
    3 Throughout the day I sometimes feel … I feel discouraged about the future                   
    4 Throughout the day I feel sad         I feel the future is hopeless and that things cannot …

每个数据帧中的变量名称都相同。

我想使用 dplyr 的 case_when 使用管道从 df1 中获取每个变量,并将其与 df2 中的相应列进行比较。

以下代码实际上可以将字符串转换为数字,但如果您注意到 case_when conditional 会检查数据帧的整行,这完全没有必要。我想用键的df2$sad 简单地检查调查中的df1$sad 变量。

    df1 %>%   mutate(across(x,~case_when(

    # The following lines of code checks a given record statement 
    # with ALL columns. Should only check indexed column
                                          . %in% df2[2,] ~ 0, #checks across all variables in df2; I just want to check a single column  
                                          . %in% df2[3,] ~ 1,
                                          . %in% df2[4,] ~ 2,
                                          . %in% df2[5,] ~ 3)))

所以,一些问题:

  1. 我不确定 case_when 可以做到这一点
  2. 如果是这样,我想知道是否需要使用点符号
  3. 或者也许有更好的解决方案

我(还)不明白的可能答案

[1.]: dplyr case_when 这可能是最好的选择...不知道如何理解这一切。

[2.]:dplyr case_when Programmatically

  1. dplyr case_when multiple cases 看起来很有希望

【问题讨论】:

    标签: r dplyr case-when programmatically


    【解决方案1】:

    我认为这需要 left_joins 而不是 case_when()。

    创建表:

    library(tidyverse)
    
    df1 <- tibble::tribble(
      ~x, ~sad, ~optimism,
      "1", "Throughout the day I sometimes feel sad", "I am somewhat optimistic about my future",
      "2", "Throughout the day I sometimes feel sad", "I am somewhat optimistic about my future",
      "3", "Throughout the day I sometimes feel happy", "I feel discouraged about the future",
      "4", "Throughout the day I sometimes feel happy", "I am optimistic about my future",
      "5", "Throughout the day I sometimes feel happy", "I am somewhat optimistic about my future",
      "6", "Throughout the day I sometimes feel happy", "I am somewhat optimistic about my future",
      "7", "Throughout the day I sometimes feel happy", "I feel discouraged about the future"
    )
    
    df2 <- tibble::tribble(
      ~y, ~sad, ~optimism,
       "1", "Throughout the day I feel happy", "I am optimistic about my future"
      ,"2", "Throughout the day I sometimes feel happy", "I am somewhat optimistic about my future"
      ,"3", "Throughout the day I sometimes feel sad", "I feel discouraged about the future"
      ,"4", "Throughout the day I feel sad", "I feel the future is hopeless and that things cannot"
    )
    

    加入查找表 df2。请注意,可以一次将查找表减少到一列(所以第一是悲伤,第二是乐观):

    df1 %>% 
      left_join(df2 %>% 
                  select(y,
                         sad), by = "sad") %>% 
      left_join(df2 %>% 
                  select(y,
                         optimism), by = "optimism") %>% 
    # columns can be renamed within the select statement which is useful to reorder the coded columns next to the text
      select(x,
             sad,
             sad_coded = y.x,
             optimism,
             optimism_coded = y.y
             )
    
    

    我希望这会有所帮助 - 如果您期待不同的输出,请告诉我。

    # A tibble: 7 x 5
      x     sad                        sad_coded optimism                  optimism_coded
      <chr> <chr>                      <chr>     <chr>                     <chr>         
    1 1     Throughout the day I some~ 3         I am somewhat optimistic~ 2             
    2 2     Throughout the day I some~ 3         I am somewhat optimistic~ 2             
    3 3     Throughout the day I some~ 2         I feel discouraged about~ 3             
    4 4     Throughout the day I some~ 2         I am optimistic about my~ 1             
    5 5     Throughout the day I some~ 2         I am somewhat optimistic~ 2             
    6 6     Throughout the day I some~ 2         I am somewhat optimistic~ 2             
    7 7     Throughout the day I some~ 2         I feel discouraged about~ 3  
    

    【讨论】:

    • 谢谢。我得出的结论是 left_join 但我现在正在努力如何使用许多变量来做到这一点。因此,除了“悲伤”和“乐观”之外,还有 20 个其他变量可以做到这一点。管道适用于一些变量,但我没有看到扩展它的方法
    • 我正在考虑改变第二个数据框的性质。我不会让它变宽,而是让它变长/变高,这样第一列将包含所有可能的调查陈述,第二列将重复 0:3。而且我认为 left_join 将适用于所有变量。
    • 是的,绝对是让 df2 更长的更好方法。
    【解决方案2】:

    您可以使用match,而不是使用case_when 并逐个匹配df2 中的每个句子,这将给出匹配索引。在base R中,你可以使用Map

    cols <- names(df1)
    df1[paste0(cols, '_num')] <- Map(match, df1[cols], df2[cols])
    
    df1
    # A tibble: 7 x 4
    #   sad                                       optimism                                sad_num optimism_num
    #  <chr>                                     <chr>                                     <int>        <int>
    #1 Throughout the day I sometimes feel sad   I am somewhat optimistic about my futu…       3            2
    #2 Throughout the day I sometimes feel sad   I am somewhat optimistic about my futu…       3            2
    #3 Throughout the day I sometimes feel happy I feel discouraged about the future           2            3
    #4 Throughout the day I sometimes feel happy I am optimistic about my future               2            1
    #5 Throughout the day I sometimes feel happy I am somewhat optimistic about my futu…       2            2
    #6 Throughout the day I sometimes feel happy I am somewhat optimistic about my futu…       2            2
    #7 Throughout the day I sometimes feel happy I feel discouraged about the future           2            3
    

    如果你想要tidyverse 选项,或者purrr 中的map2 -

    df1[paste0(cols, '_num')] <- purrr::map2(df1[cols], df2[cols], match)
    

    数据

    df1 <- structure(list(sad = c("Throughout the day I sometimes feel sad", 
    "Throughout the day I sometimes feel sad", "Throughout the day I sometimes feel happy", 
    "Throughout the day I sometimes feel happy", "Throughout the day I sometimes feel happy", 
    "Throughout the day I sometimes feel happy", "Throughout the day I sometimes feel happy"
    ), optimism = c("I am somewhat optimistic about my future", "I am somewhat optimistic about my future", 
    "I feel discouraged about the future", "I am optimistic about my future", 
    "I am somewhat optimistic about my future", "I am somewhat optimistic about my future", 
    "I feel discouraged about the future")), row.names = c(NA, -7L
    ), class = c("tbl_df", "tbl", "data.frame"))
    
    df2 <- structure(list(sad = c("Throughout the day I feel happy", "Throughout the day I sometimes feel happy", 
    "Throughout the day I sometimes feel sad", "Throughout the day I feel sad"
    ), optimism = c("I am optimistic about my future", "I am somewhat optimistic about my future", 
    "I feel discouraged about the future", "I feel the future is hopeless and that things cannot"
    )), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"
    ))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-01
      • 2020-08-30
      • 2017-12-02
      • 2018-05-27
      • 2019-04-01
      • 1970-01-01
      • 2020-04-16
      相关资源
      最近更新 更多