data.table中的分组操作

时间:2018-08-06 18:08:39

标签: r data.table

下午好,

让我们看下面的简单示例:

library(data.table)
set.seed(1L)
dt1 <- data.table(
  v1=rep(c("foo", "bar"), 2L),
  v2=runif(4L)
)
dt1[]

##      v1        v2
##  1: foo 0.2655087
##  2: bar 0.3721239
##  3: foo 0.5728534
##  4: bar 0.9082078

我想知道如何通过引用来计算和分配列v3,该列是bar元素与foo元素的除法,给出以下内容

##      v1        v2       v3
##  1: foo 0.2655087 1.401551
##  2: bar 0.3721239 1.401551
##  3: foo 0.5728534 1.585411
##  4: bar 0.9082078 1.585411

我几乎可以肯定有一种简单的方法,但是我找不到方法。

有人可以帮助我吗?谢谢!

2 个答案:

答案 0 :(得分:2)

按照@MichaelChirico的建议使用rowid,我们可以通过对值进行设置来进行除法,然后分配新列。

dt1[, v3 := (dt1[v1 == "bar", v2] / dt1[v1 == "foo", v2])[rowid(v1)]]
dt1
#     v1        v2       v3
# 1: foo 0.2655087 1.401551
# 2: bar 0.3721239 1.401551
# 3: foo 0.5728534 1.585411
# 4: bar 0.9082078 1.585411

答案 1 :(得分:2)

OP要求将每个bar元素除以其紧邻的foo元素,并将商分配给两行。

使用cumsum()

分组

可以使用update by group将其实现为cumsum(v1 == "foo"),以创建唯一的组ID:

dt1[, v3 := last(v2)/first(v2), by = cumsum(v1 == "foo")][]
    v1        v2       v3
1: foo 0.2655087 1.401551
2: bar 0.3721239 1.401551
3: foo 0.5728534 1.585411
4: bar 0.9082078 1.585411

我们也可以代替last()first()来写:

dt1[, v3 := v2[.N]/v2[1], by = cumsum(v1 == "foo")][]

使用rowid()

分组

也可以使用cumsum(v1 == "foo")代替rowid(v1)

dt1[, v3 := v2[.N]/v2[1], by = rowid(v1)][]
    v1        v2       v3
1: foo 0.2655087 1.401551
2: bar 0.3721239 1.401551
3: foo 0.5728534 1.585411
4: bar 0.9082078 1.585411