使用查找表更改数据框的多个列中的值

ver*_*his 5 lookup merge r lookup-tables multiple-columns

我试图使用查找表一次更改多个列的值。它们都使用相同的查找表。我知道如何仅对一列执行此操作-我只会使用merge,但是在处理多列时遇到了麻烦。

以下是示例数据帧和示例查找表。我的实际数据要大得多(约8列10K列)。

example <- data.frame(a = seq(1,5), b = seq(5,1), c=c(1,4,3,2,5))

lookup <- data.frame(number = seq(1,5), letter = LETTERS[seq(1,5)])

理想情况下,我将得到一个如下所示的数据框:

example_of_ideal_output <- data.frame(a = LETTERS[seq(1,5)], b = LETTERS[seq(5,1)], c=LETTERS[c(1,4,3,2,5)])

当然,在我的实际数据中,数据帧是数字,但是查找表要复杂得多,所以我不能只使用喜欢LETTERS解决问题的功能。

先感谢您!

Exp*_*teR 5

使用dplyr

f <- function(x)setNames(lookup$letter, lookup$number)[x] 
library(dplyr)
example %>% 
  mutate_each(funs(f))
#  a b c
#1 A E A
#2 B D D
#3 C C C
#4 D B B
#5 E A E
Run Code Online (Sandbox Code Playgroud)

或者与data.table

library(data.table)
setDT(example)[, lapply(.SD, f), ]
#   a b c
#1: A E A
#2: B D D
#3: C C C
#4: D B B
#5: E A E
Run Code Online (Sandbox Code Playgroud)


bgo*_*dst 4

这是一个连续使用每列的解决方案lapply()

as.data.frame(lapply(example,function(col) lookup$letter[match(col,lookup$number)]));
##   a b c
## 1 A E A
## 2 B D D
## 3 C C C
## 4 D B B
## 5 E A E
Run Code Online (Sandbox Code Playgroud)

或者,如果您不介意切换到矩阵,则可以实现“更加矢量化”的解决方案,因为矩阵将允许您对整个输入仅调用match()和索引一次:lookup$letter

matrix(lookup$letter[match(as.matrix(example),lookup$number)],nrow(example));
##      [,1] [,2] [,3]
## [1,] "A"  "E"  "A"
## [2,] "B"  "D"  "D"
## [3,] "C"  "C"  "C"
## [4,] "D"  "B"  "B"
## [5,] "E"  "A"  "E"
Run Code Online (Sandbox Code Playgroud)

(当然,您可以as.data.frame()稍后通过强制返回 data.frame,尽管如果您需要的话,您还必须恢复列名称,这可以通过 来完成setNames(...,names(example))。但是如果您真的想坚持使用 data.frame ,我的第一个解决方案可能更可取。)