首页 > 解决方案 > 使用数据值(字典)。R中的数据帧和重新编码

问题描述

我正在尝试使用包含 30 个左右变量的 data.frame。这些变量都有不同的数值(例如,“0”或“32”)。数值映射到字符串(例如,在变量 Q1 中,“0”是“Urban”;在变量 Q6 中,“32”是“不可用”)。

我在网上看到了 recode 的一些用法,以及一个执行此映射的旧plyr包以及match函数,但我没有找到任何与我所拥有的确切结构匹配的东西。

我在下面提供了一个可重现的示例:

  test <- as.data.frame(c("1", "2", "3"))
  colnames(test) <- "Q1"
    
  dictionary <- as.data.frame(c("1", "2", "3"))
  dictionary$values <- c("dog", "fish", "cat")
  dictionary$question <- c("Q1", "Q1", "Q1")
  colnames(dictionary)[1] <- "keys"

因此,这里dictionary$question包含要映射到的问题;然后“键”和“值”提供映射。因此,在测试数据框中,我有一个变量 ( Q1),它采用三个可能的值,“1”、“2”或“3”。我需要将这些映射回“狗”、“鱼”、“猫”。

但我需要一种自动方法将目标数据框中的列映射到字典中的行,然后翻译这些值,因为实际上我有超过 1000 个可能的值和 30 个变量。

编辑:我期望的是这样的函数或命令:

fun(test, dictionary)

输出:一个带有c("dog", "fish", "cat").

或者,如果 test 是c("1", "1", "1"),它将是c("dog", "dog", "dog")

标签: rdictionarymatch

解决方案


如果有很多列,则循环across“测试”列,匹配并替换从subset“字典”创建的命名向量中的值,其中“问题”与相应的列名 ( cur_column()) 匹配,然后用于coalesce填充任何 NA 值具有原始数据值

library(dplyr)
library(tibble)
test %>%
      mutate(across(everything(), ~ 
     coalesce(deframe(subset(dictionary, question == cur_column(), 
          select= -question))[as.character(.)], as.character(.))))
    Q1
1  dog
2 fish
3  cat

或者为了防止多次调用as.character,执行一次

test %>%
   mutate(across(everything(), as.character),
          across(everything(), 
           ~coalesce(deframe(subset(dictionary, question == cur_column(), 
          select= -question))[.], .)))
 Q1
1  dog
2 fish
3  cat

或使用base R

lst1 <- split(dictionary[-3], dictionary$question)
test[names(lst1)] <- Map(function(x, y) {
    tmp <- with(y,  setNames(values, keys)[as.character(x)])
     tmp[is.na(tmp)] <- x[is.na(tmp)]
     tmp}, test[names(lst1)], lst1)

推荐阅读