2017-06-18 76 views
0

我想對data.table中的行的子集執行操作,這會導致比我開始使用的行數更多。有沒有簡單的方法來擴大原來data.table以適應此?如果不是,我怎麼能做到這一點?通過在列上操作擴展data.table

以下是我原始數據的示例。

DT <- data.table(my.id=c(1,2,3), unmodified=c("a","b","c"), vals=c("apple",NA,"cat")) 
DT 
    my.id unmodified vals 
1:  1   a apple 
2:  2   b NA 
3:  3   c cat 

而這是我期望的輸出。

DT 
    my.id unmodified vals 
1:  1   a apple 
2:  2   b boy 
3:  2   b bat 
4:  2   b bag 
5:  3   c cat 

新行也可以出現在最後,我不關心順序。我嘗試了DT[my.id == 2, vals := c("boy","bat","bag")],但是它忽略了最後2個帶有警告的條目。

TIA!

編輯:我的原始數據集有大約1000萬行,儘管缺少值的條目只出現一次。如果可能,我不想創建data.table的副本。

回答

1

通過將組變量設置爲my.idunmodified,您可以使用summarize模式的data.table;每個組內此廣播值如果長度不匹配:

DT[, .(vals = if(my.id == 2) c("boy","bat","bag") else vals), .(my.id, unmodified)] 

# my.id unmodified vals 
#1:  1   a apple 
#2:  2   b boy 
#3:  2   b bat 
#4:  2   b bag 
#5:  3   c cat 
+0

謝謝!這對我的樣本完美。但是,這會創建原始data.table的副本,對嗎?我的原始數據大約有一千萬行,我需要重複幾次這個操作。參考解決方案是否有修改?我補充說,作爲剛纔對這個問題的一個編輯。 – Naumz

+2

我不認爲這可以通過引用完成,也許你可以嘗試用你想要的ID創建一個小的data.table,然後使用'rbindlist'將它與原來的一個綁定。這應該比上面的方法更快。 – Psidom

+1

是的,無法通過引用更改行集:https://stackoverflow.com/questions/10790204/how-to-delete-a-row-by-reference-in-data-table – Frank

0

另一種選擇是子集有「my.id」作爲2個而不2的數據集,然後rbind

rbind(DT[my.id == 2][, .(my.id, unmodified, vals = c('boy', 'bat', 
       'bag'))], DT[my.id != 2])[order(my.id)] 
# my.id unmodified vals 
#1:  1   a apple 
#2:  2   b boy 
#3:  2   b bat 
#4:  2   b bag 
#5:  3   c cat 
0
> DT <- data.table(my.id=c(1,2,3), unmodified=c("a","b","c"), vals=c("apple",NA,"cat")) 
> DT 
    my.id unmodified vals 
1:  1   a apple 
2:  2   b NA 
3:  3   c cat 
> DT2 <- data.table(my.id=rep(2,3), unmodified=rep("b",3), vals=c("boy","bat","bag")) 
> DT2 
    my.id unmodified vals 
1:  2   b boy 
2:  2   b bat 
3:  2   b bag 



> rbind(DT,DT2) 
    my.id unmodified vals 
1:  1   a apple 
2:  2   b NA 
3:  3   c cat 
4:  2   b boy 
5:  2   b bat 
6:  2   b bag 
> rbind(DT,DT2)[order(my.id),] 
    my.id unmodified vals 
1:  1   a apple 
2:  2   b NA 
3:  2   b boy 
4:  2   b bat 
5:  2   b bag 
6:  3   c cat 
> na.omit(rbind(DT,DT2)[order(my.id),]) 
    my.id unmodified vals 
1:  1   a apple 
2:  2   b boy 
3:  2   b bat 
4:  2   b bag 
5:  3   c cat