【问题标题】:Grouped operation in data.tabledata.table 中的分组操作
【发布时间】:2019-01-13 18:03:30
【问题描述】:

下午好,

让我们看看下面这个简单的例子:

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

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

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

【问题讨论】:

  • 如果我理解你的问题,请参阅?rowid

标签: r data.table


【解决方案1】:

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

【讨论】:

  • 谢谢@Uwe,这正是我想要的!
【解决方案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

【讨论】:

  • 另一种使用rowid的方式:dcast(dt1, rowid(v1) ~ v1, value.var="v2")[, rat := bar/foo][]
猜你喜欢
  • 2020-11-23
  • 1970-01-01
  • 2014-03-06
  • 2012-11-11
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-18
相关资源
最近更新 更多