2014-01-30 4 views
3

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

Вот простой пример.

> d <- data.table(
    value.1 = c("one", "uno", "1"), 
    value.2 = c("two", "dos", "2"), 
    name.of.col = c("value.1","value.2","value.1")) 

> d 
    value.1 value.2 name.of.col 
1:  one  two  value.1 
2:  uno  dos  value.2 
3:  1  2  value.1 

Я хотел бы добавить столбец «value.of.col», который содержит значение столбца, указанного «name.of.col».

> d 
    value.1 value.2 name.of.col value.of.col 
1:  one  two  value.1 one 
2:  uno  dos  value.2 dos 
3:  1  2  value.1 1 
+0

Спасибо за ответы. Ответы определенно работают, но очень интенсивны в памяти. Может ли кто-нибудь подумать о хорошем способе сделать это на довольно большой таблице данных? Таблица, с которой я работаю, составляет 700 тыс. Строк, 132 столбца и около 700 МБ. –

+0

делает второе решение быстрее? – agstudy

ответ

4

Другой вариант:

d[,value.of.col:=diag(as.matrix(d[,d[,name.of.col],with=F]))] 
> d 
    value.1 value.2 name.of.col value.of.col 
1:  one  two  value.1   one 
2:  uno  dos  value.2   dos 
3:  1  2  value.1   1 

EDIT добавить более быстрое решение:

d[,value.of.col:= 
     melt(d,id.vars='name.of.col')[name.of.col==variable,value]] 
+1

+1 интересное использование рециркуляции колонн и диаг; у вас есть замечательный способ думать о данных; мне никогда не приходило в голову так поступать. – BrodieG

+0

@BrodieG спасибо. Я добавляю новое решение, так как Op находит 2 решения немного медленными. – agstudy

1

Вы можете использовать матрицу индексации тянуть значения из первого и второго столбцов:

mx.idx <- d[, cbind(1:nrow(d), match(name.of.col, names(d)))] 
d[, 
    value.of.col:= 
    as.matrix(d[, 1:2, with=F])[mx.idx] 
] 
d 
# value.1 value.2 name.of.col value.of.col 
# 1:  one  two  value.1   one 
# 2:  uno  dos  value.2   dos 
# 3:  1  2  value.1   1 
1

Следующее должно быть эффективным с точки зрения памяти и немного легче читать/следовать.

for (i in unique(d[["name.of.col"]])) 
    d[ name.of.col==i, value.of.col:=get(i) ] 

d 
    value.1 value.2 name.of.col value.of.col 
1:  one  two  value.1   one 
2:  uno  dos  value.2   dos 
3:  1  2  value.1   1 
Смежные вопросы