2015-07-26 6 views
3

Я пытаюсь изменить значение числа столбцов сразу с помощью таблицы поиска. Все они используют одну и ту же таблицу поиска. Я знаю, как сделать это только для одного столбца - я бы просто использовал merge, но у меня проблемы с несколькими столбцами.Изменение значений в нескольких столбцах данных с помощью таблицы поиска

Ниже приведен пример dataframe и примерная таблица поиска. Мои фактические данные намного больше (~ 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)])

В идеале, я бы в конечном итоге с dataframe, который выглядит следующим образом:

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

Конечно, в моих фактических данных, которые dataframe это число, но таблица поиска намного сложнее, поэтому я не могу просто использовать функцию, например, LETTERS для решения задач.

Спасибо заранее!

ответ

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 

В качестве альтернативы, если вы не против перехода на матрицу, вы можете достичь «более векторизованную» решение, в качестве матрицы позволит вам звонить 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" 

(и, конечно, вы можете принудить вернуться к data.frame через as.data.frame() после этого, хотя вы должны будете Рез разорвать имена столбцов, если вы хотите их, что можно сделать с помощью setNames(...,names(example)). Но если вы действительно хотите придерживаться data.frame, мое первое решение, вероятно, предпочтительнее)

+0

Это здорово, спасибо. - - особенно цените векторизованную версию – verybadatthis

4

Использование 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