首页 > 解决方案 > 根据另一个数据框替换 R 中数据框中的字符值

问题描述

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

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 的某种变体,但我似乎无法弄清楚如何在这些函数中指定它。

标签: rdplyrtidyversedata-cleaning

解决方案


我们可以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])

推荐阅读