首页 > 解决方案 > 用 dplyr 和 mutate 解码表的漂亮解决方案

问题描述

亲爱的 dplyr/tidyverse 伙伴,我正在寻找一个很好的解决方案来解决以下问题。我只在带有循环的基础 R 中得到我的解决方案。你如何在 tidyverse 中干净利落地解决这个问题?

  1. 我有一个名为 data 的数据集,它没有有用的列名,也没有有用的值(整数)。
data <- tibble(var1 = rep(c(1:3), 2), 
               var2 = rep(c(1:3), 2))
# A tibble: 6 x 2
   var1  var2
  <int> <int>
1     1     1
2     2     2
3     3     3
4     1     1
5     2     2
6     3     3
  1. 另外我有一个编码表,它为每一列都有一个更好的名称(var1-> variable1)和一个更好的值(1->“a”)
coding <- tibble(variable = c(rep("var1", 3),rep("var2", 3)),
                     name = c(rep("variable1", 3),rep("variable2", 3)),
                     code = rep(c(1:3), 2),
                     value = rep(c("a", "b", "c"), 2)) 
# A tibble: 6 x 4
  variable name       code value
  <chr>    <chr>     <int> <chr>
1 var1     variable1     1 a    
2 var1     variable1     2 b    
3 var1     variable1     3 c    
4 var2     variable2     1 a    
5 var2     variable2     2 b    
6 var2     variable2     3 c
  1. 我正在寻找一个结果,它已将列的名称和实际值转换为数据集中的因素,比较:
result <- tibble(variable1 = factor(rep(c("a", "b", "c"), 2)), 
                 variable2 = factor(rep(c("a", "b", "c"), 2)))
# A tibble: 6 x 2
  variable1 variable2
  <fct>     <fct>    
1 a         a        
2 b         b        
3 c         c        
4 a         a        
5 b         b        
6 c         c

感谢您的承诺 :) :) :) :)

标签: rtidyversedplyr

解决方案


任意数量列的通用解决方案 -

  • 创建一个行号列来标识每一行
  • 获取data长格式
  • coding为每个值加入它
  • 只保留唯一的行并以宽格式取回。
library(dplyr)
library(tidyr)

data %>%
  mutate(row = row_number()) %>%
  pivot_longer(cols = -row, values_to = 'code')  %>%
  left_join(coding, by = 'code') %>%
  select(row, name = name.y, value) %>%
  distinct() %>%
  pivot_wider() %>%
  select(-row)

# variable1 variable2
#  <chr>     <chr>    
#1 a         a        
#2 b         b        
#3 c         c        
#4 a         a        
#5 b         b        
#6 c         c        

推荐阅读