2015-08-27 5 views
3

У меня очень уродливый набор данных, который представляет собой плоский файл реляционной базы данных. Минимальный воспроизводимый пример здесь:Передать переменную как имя столбца для dplyr?

df <- data.frame(col1 = c(letters[1:4],"c"), 
        col1.p = 1:5, 
        col2 = c("a","c","l","c","l"), 
       col2.p = 6:10, 
        col3= letters[3:7], 
       col3.p = 11:20) 

мне нужно, чтобы быть в состоянии определить значение «.p» для „Col #“, который имеет „с“. Мой предыдущий вопрос о SO получил первую часть: In R, find the column that contains a string in for each row. Который я предоставляю для контекста.

tmp <- which(projectdata=='Transmission and Distribution of Electricity', arr.ind=TRUE) 
cnt <- ave(tmp[,"row"], tmp[,"row"], FUN=seq_along) 
maxnames <- paste0("max",sequence(max(cnt))) 
projectdata[maxnames] <- NA 
projectdata[maxnames][cbind(tmp[,"row"],cnt)] <- names(projectdata)[tmp[,"col"]] 
rm(tmp, cnt, maxnames) 

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

df 
    col1 col1.p col2 col2.p col3 col3.p max1 
1  a  1 a  6 c  11 col3 
2  b  2 c  7 d  12 col2 
3  c  3 l  8 e  13 col1 
4  d  4 c  9 f  14 col2 
5  c  5 l  10 g  15 col1 
6  a  1 a  6 c  16 col3 
7  b  2 c  7 d  17 col2 
8  c  3 l  8 e  18 col1 
9  d  4 c  9 f  19 col2 
10 c  5 l  10 g  20 col1 

Когда я попытался получить «.P» соответствует значение в „max1“, я продолжал получать ошибки. Я думал, что этот подход будет:

df %>% 
    mutate(my.p = eval(as.name(paste0(max1,'.p')))) 
Error: object 'col3.p' not found 

Очевидно, что это не сработало, так что я, возможно, думал, что это было похоже на пропускание имени столбца в функции, где мне нужно использовать «получить». Это тоже не сработало.

df %>% 
    mutate(my.p = get(as.name(paste0(max1,'.p')))) 
Error: invalid first argument 
df %>% 
    mutate(my.p = get(paste0(max1,'.p'))) 
Error: object 'col3.p' not found 

Я нашел то, что избавляется от этой ошибки, используя data.table от другого, но связанные с ним проблемы, здесь: http://codereply.com/answer/7y2ra3/dplyr-error-object-found-using-rle-mutate.html. Тем не менее, он дает мне «col3.p» для каждой строки. Это Max1 для первой строки, df$max1[1]

library('dplyr') 
library('data.table') # must have the data.table package 
df %>% 
    tbl_dt(df) %>% 
    mutate(my.p = get(paste0(max1,'.p'))) 

Source: local data table [10 x 8] 

    col1 col1.p col2 col2.p col3 col3.p max1 my.p 
1  a  1 a  6 c  11 col3 11 
2  b  2 c  7 d  12 col2 12 
3  c  3 l  8 e  13 col1 13 
4  d  4 c  9 f  14 col2 14 
5  c  5 l  10 g  15 col1 15 
6  a  1 a  6 c  16 col3 16 
7  b  2 c  7 d  17 col2 17 
8  c  3 l  8 e  18 col1 18 
9  d  4 c  9 f  19 col2 19 
10 c  5 l  10 g  20 col1 20 

Использование lazyevalinterp подход (от этого так: Hot to pass dynamic column names in dplyr into custom function?) не работает для меня. Возможно, я неправильно ее реализую?

library(lazyeval) 
library(dplyr) 
df %>% 
    mutate_(my.p = interp(~colp, colp = as.name(paste0(max1,'.p')))) 

Я получаю сообщение об ошибке:

Error in paste0(max1, ".p") : object 'max1' not found 

В идеале, у меня будет новый столбец my.p равняться соответствующей p на основе столбца, указанного в max1.

Я могу сделать это все с помощью ifelse, но я стараюсь сделать это с меньшим количеством кода и сделать его применимым к следующей уродливой плоской таблице.

+0

Если вы используете 'data.table'. 'setDT (df) [, my.p: = get (paste0 (max1, '.p')), 1: nrow (df)]' должен получить желаемый результат – akrun

+1

Я не уверен, почему этот ответ doesn ' t похоже на ответ, @akrun, но он работает. Если он превратится в ответ, я могу принять его. Спасибо за вашу помощь. Почему это не работает, чтобы вставить dplyr 'mutate (my.p = get (paste0 (max1, '.p'))'? Я бы очень хотел это понять. – jessi

+0

Спасибо, что согласились. с dplyr, чтобы найти краткое решение, пока ничего не получилось. – akrun

ответ

0

Мы можем сделать это с помощью data.table. Мы преобразуем «data.frame» в «data.table» (setDT(df)), сгруппированные по последовательности строк, и получим значение paste и присвойте его (:=) в новый столбец ('my.p').

library(data.table) 
setDT(df)[, my.p:= get(paste0(max1, '.p')), 1:nrow(df)] 
df 
# col1 col1.p col2 col2.p col3 col3.p max1 my.p 
# 1: a  1 a  6 c  11 col3 11 
# 2: b  2 c  7 d  12 col2 7 
# 3: c  3 l  8 e  13 col1 3 
# 4: d  4 c  9 f  14 col2 9 
# 5: c  5 l  10 g  15 col1 5 
# 6: a  1 a  6 c  16 col3 16 
# 7: b  2 c  7 d  17 col2 7 
# 8: c  3 l  8 e  18 col1 3 
# 9: d  4 c  9 f  19 col2 9 
#10: c  5 l  10 g  20 col1 5 
Смежные вопросы