2017-04-26 46 views
1

我要替換在一個data.table柱(COL1)的所有值在data.table列值。 我以爲試圖在循環中做到這一點,但只有很少的值被替換。 實施例:R:有條件更換過環

#Generate data.table 
library(data.table) 
dt2 <- data.table(col1=rep(c("a","b","c","d"),each=2), col2=rep(c(1,2,3,4),2),col3=rep(c(1,2,3,4),2)) 
> dt2 
    col1 col2 col3 
1: a 1 1 
2: a 2 2 
3: b 3 3 
4: b 4 4 
5: c 1 1 
6: c 2 2 
7: d 3 3 
8: d 4 4 

變化值:在COL1

#new col1 elements 
new_col1 = c("WT","m1","m9","m10") 
#change col1 
col1_names = unique(dt$col1) 
for (i in 1:length(col1_names)){ 
    dt2[col1==col1_names[i],col1:=new_col1[i]] 
    } 
> dt2 
    col1 col2 col3 
1: WT 1 1 
2: WT 2 2 
3: m1 3 3 
4: m1 4 4 
5: c 1 1 
6: c 2 2 
7: d 3 3 
8: d 4 4 

值僅是部分地取代。 任何人都可以解釋它或建議更好的方式如何更換?

我試圖立刻取代他們,但這並不無論是正常工作:

#generate data.table 
dt2 <- data.table(col1=rep(c("a","b","c","d"),each=2), col2=rep(c(1,2,3,4),2),col3=rep(c(1,2,3,4),2)) 

    col1 col2 col3 
1: a 1 1 
2: a 2 2 
3: b 3 3 
4: b 4 4 
5: c 1 1 
6: c 2 2 
7: d 3 3 
8: d 4 4 
#replace values 
col1_names = unique(dt$col1) 
dt2[col1==col1_names,col1:=new_col1] 
> dt2 
    col1 col2 col3 
1: WT 1 1 
2: m1 2 2 
3: m9 3 3 
4: m10 4 4 
5: WT 1 1 
6: m1 2 2 
7: m9 3 3 
8: m10 4 4 

值只是更換不帶任何條件。

+1

你可以用'match'找到基於該更換'DT2 [位置和, COL1:= new_col1 [匹配(COL1,GROUP_NAMES)]]' – akrun

+0

我會創建一個查找表,然後使用更新聯接 –

+0

我發現,當我使用:col1_names =名單(獨特(DT $ COL1)),那麼它的工作原理。但是不明白爲什麼列表能夠工作。 – luida

回答

1

我同意查找表的答案。你可能也想嘗試:

library(data.table) 

dt2 <- data.table(col1=rep(c("a","b","c","d"),each=2), 
        col2=rep(c(1,2,3,4),2), 
        col3=rep(c(1,2,3,4),2)) 

new_col1 <- c(a="WT",b="m1",c="m9",d="m10") # .. have to change slightly 

dt2$col1<-unname(new_col1[dt2$col1]) 

或用data.table「更新加入」語法:

lookup = data.table(old = c("a","b","c","d"), new = c("WT","m1","m9","m10")) 
dt2[lookup, on=.(col1 = old), col1 := i.new ] 
+0

我最終使用akrun建議,因爲它更通用。可以使用相同的矢量「new_col1」,然後使用不同的數據。表中的col1值可能不同。不過謝謝 – luida