2015-10-16 2 views
1

Я хочу обновить значения столбца в таблице data.table, привязанные к двум другим столбцам в одной таблице.Обновление значений с использованием lapply в data.table условно для nrow

Этот код здесь работает некорректно, но я хотел обновить значения в своем DT вместо того, чтобы возвращать список DT.

воспроизводимый пример:

library(data.table) 
library(gtools) 

# Create Data Table 
    DT <- as.data.table(combinations(3,2,1:3,repeats=TRUE)) 
    DT[, V3 := 9999 ] 

DT 
> V1 V2 V3 
>1: 1 1 9999 
>2: 1 2 9999 
>3: 1 3 9999 
>4: 2 2 9999 
>5: 2 3 9999 
>6: 3 3 9999 

Мой код:

# create function 

stationary <- function(i) {DT[i, V3 := if (V1==V2) 0 else V1+V2 ]} 

i <- 1:nrow(DT) 

DT <- lapply(i, stationary) # This returns a list of identical data tables 

В результате я хотел:

DT 
> V1 V2 V3 
>1: 1 1 0 
>2: 1 2 3 
>3: 1 3 4 
>4: 2 2 0 
>5: 2 3 5 
>6: 3 3 0 
+1

Итерация по всем наблюдениям всегда медленная. Вы могли бы хотя бы использовать 'ifelse'. – Roland

+0

Я изначально рассматривал цикл с 'if else'. Я все еще склоняюсь к лучшему подходу к моей проблеме. Возможно, мне придется опубликовать еще один вопрос. –

+1

Я написал 'ifelse', который является векторизованной функцией, а не' if else'. – Roland

ответ

4

Я хотел бы сделать это:

DT[, V3 := (V1 + V2) * (V1 != V2)] 
# V1 V2 V3 
#1: 1 1 0 
#2: 1 2 3 
#3: 1 3 4 
#4: 2 2 0 
#5: 2 3 5 
#6: 3 3 0 

Это быстро и просто.

+0

Я думаю, вы были сорваны там. Хотя я предполагаю, что ваше решение слишком сложно для понимания OP. Например, они, вероятно, не понимают, что '(V1! = V2)' становится двоичным вектором, а умножается на '(V1 + V2)'. Возможно, стоит добавить объяснения для будущих читателей-новичков. –

+0

Я не уверен, что меня сорвали. Решение @ jangorecki может избежать векторного сканирования и использовать двоичный поиск и, следовательно, может быть быстрее. – Roland

+0

бинарный поиск по каким? Он не заходил ни в какой столбец, и при запуске '==' on и unkeyed data.table это будет скорее медленнее, потому что сначала попытается установить вторичный ключ. Но в этом случае он сравнивает две разные переменные каждый раз вместо переменной в зависимости от значения, как данные будут входить в такую ​​ситуацию? Может быть, 'V1'? Тем не менее, первый запуск не должен быть быстрее AFAIK. В любом случае, я думаю, что скорость торговли будет незначительной по сравнению с чрезмерно сложным кодом IMO. –

2

Вы можете использовать цепочки:

library(data.table) 
library(gtools) # combinations() 
DT <- as.data.table(combinations(3,2,1:3,repeats=TRUE)) 
DT[, V3 := 9999 ] 
DT[V1==V2, V3 := 0 
    ][V1!=V2, V3 := as.numeric(V1+V2) 
    ][] 
# V1 V2 V3 
# 1: 1 1 0 
# 2: 1 2 3 
# 3: 1 3 4 
# 4: 2 2 0 
# 5: 2 3 5 
# 6: 3 3 0 

Вы можете избежать as.numeric вызова, если вы вставляете с целыми числами, так и V3 := 9999LV3 := 0L.

+0

Hmm ,,, который выглядит очень излишне сложным, вызывая цифру '[.data.table' (цепочка) и фильтры .... Я бы назвал это ответом' dplyr' под маскировкой 'data.table'. –

+0

Согласен, но гораздо проще расширить это решение в более сложных случаях. – jangorecki