2017-02-21 4 views
1

Скажем, у меня есть таблица данных, и я хочу, чтобы вычислить новую переменную на основе нескольких условий старых переменных, как это:Как использовать сложный результат из пасты внутри части «i» таблицы data.table?

library(data.table) 
test <- data.table(a = c(1,1,0), b = c(0,1,0), c = c(1,1,1)) 

test[a==1 & b==1 & c==1,test2:=1] 

Но я на самом деле имеют гораздо больше условий (все комбинации различных переменных), которые также имеют разную длину. Я рисую те из списка, такие как:

conditions<-list(c("a","b","c"), c("b","c")) 

, а затем я хочу, чтобы перебрать этот список и построить вектор символов, как это (с которым я хочу сделать что-то, прежде чем удалить его и переходить к следующему элементу список):

mystring <- paste0(paste0(conditions[[1]], collapse = "==1 & "), "==1") 

Но как я могу использовать "MyString" внутри data.table? as.function() или get() или eval(), похоже, не работают. Что-то вроде:

test[mystring,test3:=1] 

- это то, что я ищу.

+0

Не ясно, что «mychars» есть. – Frank

+1

mystring, извините, была более ранней версией –

+1

Хорошо, есть 'test [eval (parse (text = mystring)), test3: = 1]', но это довольно сильно обескураживает в data.table и R вообще, чтобы играть с строки как код. Кроме того, data.table имеет лучшие способы обработки такого рода фильтров и обновлений. Возможно, вам захочется просмотреть свои виньетки. – Frank

ответ

2

Для данного варианта использования вы можете использовать соединение с on = для достижения желаемой цели без необходимости создания и оценки сложных строк условий.

Вместо

test[a==1 & b==1 & c==1, test2 := 1][] 

мы можем написать

test[.(1, 1, 1), on = c("a", "b", "c"), test2 := 1][] 
# a b c test2 
#1: 1 0 1 NA 
#2: 1 1 1  1 
#3: 0 0 1 NA 

Теперь OP было предложено перебрать список условий с использованием lapply() "чтобы сделать что-то". Это может быть достигнуто следующим образом

# create list of conditions for subsetting 
col = list(c("a","b","c"), c("b","c")) 
val = list(c(1, 1, 1), c(0, 1)) 
# loop over conditions 
lapply(seq_along(col), function(i) test[as.list(val[[i]]), on = col[[i]], test2 := i]) 
#[[1]] 
# 
#[[2]] 
# a b c test2 
#1: 1 0 1  2 
#2: 1 1 1  1 
#3: 0 0 1  2 

Обратите внимание, что выход lapply() не используется, потому что test был изменен вместо:

test 
# a b c test2 
#1: 1 0 1  2 
#2: 1 1 1  1 
#3: 0 0 1  2 
Смежные вопросы