2014-11-24 33 views
4

背景加入,并添加列去

我是相当新的data.table库,目前正在学习有效地使用它。我在这里有两个表格,我想先聚合第二个表格,然后将它与第一个表格合并并修改连接表格中的一列。理想(和我的理解)在一个去。

包版本

sessionInfo() 
# R version 3.1.0 (2014-04-10) 
# Platform: i386-w64-mingw32/i386 (32-bit) 

# attached base packages: 
# [1] stats  graphics grDevices utils  datasets methods base  

# other attached packages: 
# [1] data.table_1.9.4 

# loaded via a namespace (and not attached): 
# [1] chron_2.3-45 plyr_1.8.1 Rcpp_0.11.2 reshape2_1.4 stringr_0.6.2 
# [6] tools_3.1.0  

代码

我已经试过可以在这个小例子可以看出:

library(data.table) 
set.seed(1) 
DT1 <- data.table(id = LETTERS[1:4], x = rnorm(4), key = "id") 
DT2 <- data.table(id = rep(LETTERS[1:4], each = 3), y = 1:12, z = rep(1, 12), key = "id") 
DT1[DT2[, lapply(.SD, mean), by = "id"]] # simple join works fine 
# id   x y z 
# 1: A -0.6264538 2 1 
# 2: B 0.1836433 5 1 
# 3: C -0.8356286 8 1 
# 4: D 1.5952808 11 1 

# however, adding a 'j' argument does not work 
DT1[DT2[, lapply(.SD, mean), by = "id"], x := -x] # (1) 

# in fact the above statement changes the 'x' column in 'DT1': 
DT1 
# id   x 
# 1: A 0.6264538 
# 2: B -0.1836433 
# 3: C 0.8356286 
# 4: D -1.5952808 

我猜想,这事做data.table如何处理数据(并且不进行复制)除非需要,所以请参考)。因此,下面的代码工作:

DT3 <- copy(DT1[DT2[, lapply(.SD, mean), by = "id"]])[, x := -x] 
(DT4 <- DT1[DT2[, lapply(.SD, mean), by = "id"]][, x := -x]) # (2) 
# id   x y z 
# 1: A -0.6264538 2 1 
# 2: B 0.1836433 5 1 
# 3: C -0.8356286 8 1 
# 4: D 1.5952808 11 1 
identical(DT3, DT4) 
# [1] TRUE 

问题

  1. 是什么做的 '最好' 的方法是什么?在时间和记忆方面使用“最佳”?
  2. 这样做的概念性方式是什么?换句话说,Matt Dowle(软件包维护者)会使用哪一系列命令?
  3. 为什么(1)不工作,而(2)按预期工作?
+0

我们应该经常问自己,WWMDD? – 2014-11-24 16:40:19

回答

3

与目前执行的问题(1)

DT1[DT2[, lapply(.SD, mean), by = "id"], x := -x] # (1) 

是,你是通过参考与x:=-x修改DT1,用的加入实际上没有分配。

你想要的是(4)

DT3 <- DT1[DT2[, lapply(.SD, mean), by = "id"]][, x := -x] 

在这里,一个额外的呼叫[上加入了数据集中意味着你分配到新创建的data.table x:=-x

除非确实需要,否则不需要显式复制。

+0

感谢您的解释。我认为它与通过引用更改插槽有关。只是出于好奇:是否在(2)情况下复制'data.table'? – thothal 2014-11-25 06:55:59

+1

@thothal新数据。table是用'DT1 [DT2 [,lapply(.SD,mean),by =“id”]]'创建的,在copy中复制将复制这个新的数据表(据我所知) – mnel 2014-11-26 02:34:55

2

这里是我如何与dplyr解决这个:

library("dplyr") 

set.seed(1) 
DT1 <- data_frame(id = LETTERS[1:4], x = rnorm(4), key = "id") 
DT2 <- data_frame(id = rep(LETTERS[1:4], each = 3), y = 1:12, z = rep(1, 12), key = "id") 

DT2 %>% 
    group_by(id) %>% 
    summarise_each(funs(mean), y:z) %>% 
    left_join(DT1) %>% 
    mutate(x = -x) 

(假设我正确地解释你的data.table代码)

+0

感谢您的选择。其实,这是我的第一个代码。但是,我只是想探索'data.table'选项来学习新的东西。 – thothal 2014-11-25 07:00:02