根据另一个数据帧从R中的一个数据帧替换字符值

时间:2020-03-19 18:55:29

标签: r dplyr tidyverse data-cleaning

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

这是我的看法:

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

然后,将较长的数据集与您的密码本合并以获得新名称。

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

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创建

有关旋转的更多信息,请看一下提迪尔的Pivoting vignette