【问题标题】:Replacing character values from a data frame in R, based on another data frame根据另一个数据框替换 R 中数据框中的字符值
【发布时间】:2020-03-19 18:55:29
【问题描述】:

我正在尝试根据值的“码本”替换数据框中的大量值。我有两个小标题:

head(df)
# A tibble: 6 x 6
  responseid color  q1_first_choice q1_second_choice q1_third_choice 
       <dbl> <chr>  <chr>           <chr>            <chr>                     
1         34 red    q1_red_b        q1_red_a         Pomegranate     
2         35 blue   q1_blue_a       q1_blue_c        q1_blue_b       
3         36 green  Tangerine       q1_green_b       q1_green_a      
4         37 purple q1_purple_b     q1_purple_a      q1_purple_c     
5         38 red    q1_red_a        Watermelon       q1_red_c        
6         39 green  q1_green_a      q1_green_c       q1_green_b    

head(codes)
# A tibble: 6 x 2
  Code      Name     
  <chr>     <chr>    
1 q1_red_a  Apple    
2 q1_red_b  Raspberry
3 q1_red_c  Cherry   
4 q1_blue_a Banana   
5 q1_blue_b Orange   
6 q1_blue_c Pineapple

我想用代码$Name 值替换大量列中的 df 值。在命令中输入的值太多,所以我想引用代码中的列。

我想答案可能是 case_when、recode 或 chartr 的某种变体,但我似乎无法弄清楚如何在这些函数中指定它。

【问题讨论】:

  • 如果你能提供一个reprex,那将有很大帮助。只需在控制台中输入 dput(data frame name),然后粘贴输出。
  • 我假设您在 'df' 中存在的 'code' 数据集中拥有所有相应的 'Code'。在head 显示的数据中,某些值在“代码”数据集中没有对应的匹配项

标签: r dplyr tidyverse data-cleaning


【解决方案1】:

我们可以使用mutate_at 遍历以“q1”开头的列,并通过传递从“codes”数据集创建的命名向量来进行替换

library(dplyr)
df %>%
    mutate_at(vars(starts_with('q1')), ~  setNames(codes$Name, codes$Code)[.])

或者另一种选择是在整形为“长”格式后执行left_join

library(tidyr)
df %>%
   pivot_longer(cols = -c(responseid, color)) %>% 
   left_join(codes, by = c('value' = 'Code')) %>%
   mutate(value = coalesce(Name, value)) %>% 
   select(-Name) %>% 
   pivot_wider(names_from = name, values_from = value)

或使用base R

i1 <- startsWith(names(df), "q1")
v1 <- setNames(codes$Name, codes$Code)
df[i1] <- lapply(df[i1], function(x) v1[x])

【讨论】:

    【解决方案2】:

    这是我的看法:

    首先,将数据集转换为长格式。如果在每列之间共享响应选择,这将特别有用。

    然后,将长数据集与您的密码本连接起来以获取新名称。

    最后,(可选?)将两列合并在一起,以保留未出现在您的码本中的响应选择。我之所以说是可选的,是因为仅当原始响应选项未出现在您的密码本中时才需要此步骤。

    library(tidyverse)
    
    df <- tribble(
      ~responseid,   ~color,  ~q1_first_choice, ~q1_second_choice, ~q1_third_choice,
               34,    "red",        "q1_red_b",        "q1_red_a",    "Pomegranate",
               35,   "blue",       "q1_blue_a",       "q1_blue_c",      "q1_blue_b",
               36,  "green",       "Tangerine",      "q1_green_b",     "q1_green_a",
               37, "purple",     "q1_purple_b",     "q1_purple_a",    "q1_purple_c",
               38,    "red",        "q1_red_a",      "Watermelon",       "q1_red_c",
               39,  "green",      "q1_green_a",      "q1_green_c",     "q1_green_b"
    )
    
    codes <- tribble(
            ~Code,       ~Name,
       "q1_red_a",     "Apple",
       "q1_red_b", "Raspberry",
       "q1_red_c",    "Cherry",
      "q1_blue_a",    "Banana",
      "q1_blue_b",    "Orange",
      "q1_blue_c", "Pineapple"
    )
    
    df_long <- df %>%
      pivot_longer(
        cols = starts_with("q"),
        values_to = "Code"
      )
    df_long
    #> # A tibble: 18 x 4
    #>    responseid color  name             Code       
    #>         <dbl> <chr>  <chr>            <chr>      
    #>  1         34 red    q1_first_choice  q1_red_b   
    #>  2         34 red    q1_second_choice q1_red_a   
    #>  3         34 red    q1_third_choice  Pomegranate
    #>  4         35 blue   q1_first_choice  q1_blue_a  
    #>  5         35 blue   q1_second_choice q1_blue_c  
    #>  6         35 blue   q1_third_choice  q1_blue_b  
    #>  7         36 green  q1_first_choice  Tangerine  
    #>  8         36 green  q1_second_choice q1_green_b 
    #>  9         36 green  q1_third_choice  q1_green_a 
    #> 10         37 purple q1_first_choice  q1_purple_b
    #> 11         37 purple q1_second_choice q1_purple_a
    #> 12         37 purple q1_third_choice  q1_purple_c
    #> 13         38 red    q1_first_choice  q1_red_a   
    #> 14         38 red    q1_second_choice Watermelon 
    #> 15         38 red    q1_third_choice  q1_red_c   
    #> 16         39 green  q1_first_choice  q1_green_a 
    #> 17         39 green  q1_second_choice q1_green_c 
    #> 18         39 green  q1_third_choice  q1_green_b
    
    df_out <- df_long %>%
      left_join(codes, by = "Code") %>%
      mutate(Code = coalesce(Name, Code)) %>%
      select(responseid, color, name, Code) %>%
      pivot_wider(
        names_from = "name",
        values_from = "Code"
      )
    df_out
    #> # A tibble: 6 x 5
    #>   responseid color  q1_first_choice q1_second_choice q1_third_choice
    #>        <dbl> <chr>  <chr>           <chr>            <chr>          
    #> 1         34 red    Raspberry       Apple            Pomegranate    
    #> 2         35 blue   Banana          Pineapple        Orange         
    #> 3         36 green  Tangerine       q1_green_b       q1_green_a     
    #> 4         37 purple q1_purple_b     q1_purple_a      q1_purple_c    
    #> 5         38 red    Apple           Watermelon       Cherry         
    #> 6         39 green  q1_green_a      q1_green_c       q1_green_b
    

    reprex package (v0.3.0) 于 2020-03-19 创建

    有关旋转的更多信息,请查看 tidyr 中的 Pivoting vignette

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 1970-01-01
      • 2019-03-23
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      相关资源
      最近更新 更多