使用查找更改数据框多列中的值 table
Change values in multiple columns of a dataframe using a lookup table
我正在尝试使用查找一次更改多个列的值 table。他们都使用相同的查找 table。我知道如何只对一列执行此操作——我只使用 merge
,但在处理多列时遇到问题。
下面是一个示例数据框和一个示例查找 table。我的实际数据要大得多(约 10K 列,8 行)。
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)])
当然,在我的实际数据中数据帧是数字,但是查找table要复杂得多,所以我不能只使用LETTERS
这样的函数来解决问题。
提前致谢!
这是一个解决方案,它使用 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
或者,如果您不介意切换到矩阵,您可以实现 "more vectorized" 解决方案,因为矩阵允许您调用 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"
(当然你可以在之后通过 as.data.frame()
强制回到 data.frame,尽管如果你想要它们你也必须恢复列名,这可以用 setNames(...,names(example))
。但如果你真的想坚持使用 data.frame,我的第一个解决方案可能更可取。)
使用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
或者用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
我正在尝试使用查找一次更改多个列的值 table。他们都使用相同的查找 table。我知道如何只对一列执行此操作——我只使用 merge
,但在处理多列时遇到问题。
下面是一个示例数据框和一个示例查找 table。我的实际数据要大得多(约 10K 列,8 行)。
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)])
当然,在我的实际数据中数据帧是数字,但是查找table要复杂得多,所以我不能只使用LETTERS
这样的函数来解决问题。
提前致谢!
这是一个解决方案,它使用 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
或者,如果您不介意切换到矩阵,您可以实现 "more vectorized" 解决方案,因为矩阵允许您调用 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"
(当然你可以在之后通过 as.data.frame()
强制回到 data.frame,尽管如果你想要它们你也必须恢复列名,这可以用 setNames(...,names(example))
。但如果你真的想坚持使用 data.frame,我的第一个解决方案可能更可取。)
使用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
或者用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