2015-10-16 56 views
1

我想將data.table條件中的列的值更新爲同一個表中的其他兩列。在data.table中使用lapply更新值條件爲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

二進制搜索什麼?他沒有按任何列鍵,當運行'=='並且未加密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

嗯,,,看起來非常不必要的複雜,同時調用數字'[.data.table'(鏈接)和過濾器....我會稱這是'data.table'僞裝下的'dplyr'回答。 –

+0

我同意,但將此解決方案擴展到更復雜的情況要容易得多。 – jangorecki