用data.table替换data.frame元素操作(使用rowname)

时间:2014-08-22 16:16:00

标签: r data.table

所以我想说我有以下data.frame s:

df1 <- data.frame(y = 1:10, z = rnorm(10), row.names = letters[1:10])
df2 <- data.frame(y = c(rep(2, 5), rep(5, 5)), z = rnorm(10),
    row.names = letters[1:10]) 

也许是“等效的”data.table s:

dt1 <- data.table(x = rownames(df1), df1, key = 'x')
dt2 <- data.table(x = rownames(df2), df2, key = 'x')

如果我想在df1df2之间进行按元素操作,它们看起来像

dfRes <- df1 / df2

保留rownames()

R> head(dfRes)
    y          z
a 0.5  3.1405463
b 1.0  1.2925200
c 1.5  1.4137930
d 2.0 -0.5532855
e 2.5 -0.0998303
f 1.2 -1.6236294

我对data.table的理解不足说同样的操作应该是这样的:

dtRes <- dt1[, !'x', with = F] / dt2[, !'x', with = F]
dtRes[, x := dt1[,x,]]
setkey(dtRes, x)

setkey可选)

有更多的data.table - esque方式吗?

作为一个稍微相关的一点,更一般地说,我会在每个data.table中有其他列,例如因素,我想在执行元素操作时省略这些列,但仍然在结果中有它们。这有意义吗?

谢谢!

1 个答案:

答案 0 :(得分:4)

IMO正确的方法是使用 join - 它将负责将列与行名称正确匹配。

我将使用data.table v1.9.3进行说明。您可以在github project page上找到安装说明。

## 1.9.3 
dt1[dt2, list(x, y=y/i.y, z=z/i.z)]
#      x   y           z
#  1: a 0.5  6.20339701
#  2: b 1.0  1.72701257
#  3: c 1.5  0.11444594
#  4: d 2.0 -0.70715087
#  5: e 2.5 -0.41692176
#  6: f 1.2  0.07033400
#  7: g 1.4  0.45198379
#  8: h 1.6 -0.04762567
#  9: i 1.8 -1.46270143
# 10: j 2.0 -0.92588495

i.yi.z分别在加入期间引用data.table dt2列。

  

如果您有更多列,则可以构建表达式并对其进行评估。您可以在[r] [data.table]标记下的SO上找到许多此类帖子。


如果你想坚持使用CRAN版本(1.9.2),那么你可以这样做:

## 1.9.2
dt1[dt2, list(y=y/i.y, z=z/i.z)]

您不需要x,因为它默认返回键列。


对于那些对两个版本之间的差异感兴趣的人:

  

在版本&lt;在data.table的1.9.3中,表单x[i, list(...)]的连接 - 也就是提供j的位置 - 此处为list(...),隐式执行 by-without -by 操作。也就是说,它为ji匹配的关键列的每个值计算x。虽然这是一个很棒的功能,但是没有办法选择退出它。因此,不需要 by-without-by 的操作稍慢......

     

因此,在v1.9.3 +版本中,我们已将隐式 - (或 by-without-by )功能替换为 by < / em> 明确,为by = .EACHI

     

也就是说,在v1.9.3 +中:x[i, list(...)]将首先计算i然后计算j,而不是每个i

     

并且,x[i, list(...), by=.EACHI]将为每个 j计算i - 这相当于在版本中执行联接的方式&lt; 1.9.3。

希望这有助于理解差异。