2017-06-18 74 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