2016-08-17 55 views
1

我有以下data.tables:data.table參考列的名字

Comparison <- data.table(code = c("AAA", "BBB"), 
         elem1 = c(1, 2), 
         elem2 = c(4, 4)) 

DT <- data.table(A = c("AAA", "AAA", "AAA", "AAA"), 
       B = c("BBB", "BBB", "BBB", "BBB"), 
       C = c(1, 2, 3, 4)) 

現在,我想從Comparison添加基於列的比較新的列和從DT。下面的命令生成所期望的輸出:

DT[, newCol := {ifelse(abs(C - Comparison[code == "AAA", elem2]) == 0, "0", "1")}] 

Output: 

    A B C newCol 
1: AAA BBB 1  1 
2: AAA BBB 2  1 
3: AAA BBB 3  1 
4: AAA BBB 4  0 

然而,如果不是硬編碼列A的列值,我使用了柱本身與此:

DT[, newCol := {ifelse(abs(C - Comparison[code == A, elem2]) > 0, "0", "1")}] 

它輸出以下錯誤,這我不知道如何避免:

Error in `[.data.table`(Comparison, code == A, elem2) : 
    RHS of == is length 4 which is not 1 or nrow (2). For robustness, no recycling is allowed (other than of length 1 RHS). Consider %in% instead. 

在我看來,該操作未矢量化的列元素AØ f DT in Comparison,我不太明白爲什麼,因爲C列的元素是正確的(即,它單獨使用C的元素,但不使用A的元素)。我怎麼能做這個比較?

任何幫助將不勝感激。

回答

1

如果你讀了錯誤信息,它說Consider %in% instead.

事實上與%in%它的工作原理更換==,而不必使用joinmerge我們可以使用joinon

DT[Comparison, newCol := as.integer(C != elem2), on = c("A" = "code"), nomatch = 0] 
DT 
#  A B C newCol 
#1: AAA BBB 1  1 
#2: AAA BBB 2  1 
#3: AAA BBB 3  1 
#4: AAA BBB 4  0 
1

一個解決方案是做數據合併。

require(data.table) 

Comparison <- data.table(code = c("AAA", "BBB"), 
         elem1 = c(1, 2), 
         elem2 = c(4, 4)) 
Comparison 

DT <- data.table(A = c("AAA", "AAA", "AAA", "AAA"), 
       B = c("BBB", "BBB", "BBB", "BBB"), 
       C = c(1, 2, 3, 4)) 
DT 

tmp <- merge(DT, Comparison, by.x = "A", by.y = "code") 
tmp[, newCol := as.character(as.integer(C != elem2))] 
tmp 
0

DT[, newCol := {ifelse(abs(C - Comparison[code %in% A, elem2]) = 0, "0", "1")} 

DT 

#  A B C newCol 
#1: AAA BBB 1  1 
#2: AAA BBB 2  1 
#3: AAA BBB 3  1 
#4: AAA BBB 4  0