下午好,
让我们看下面的简单示例:
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
我几乎可以肯定有一种简单的方法,但是我找不到方法。
有人可以帮助我吗?谢谢!
答案 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