【发布时间】:2018-11-25 17:16:28
【问题描述】:
我是 dplyr 的新手,我正在努力解决我认为是一个简单的功能。我有一个类似于的数据集:
require(dplyr)
dat <- data.frame(t = rep(seq(1, 5, 1),4), id = rep(c(rep("A",5), rep("B",5), rep("C",5), rep("D",5)), 1),
x = 1:20, y = 51:70, h = c(rep(1,10), rep(0,10) ) )
dat <- arrange(dat, t)
dat <- data.frame(dat, group = c("B", "A", "A", "A", "A", "B", "C", "D", "A", "B", "D", "C", "A", "D", "C", "A", "A", "C", "C", "B") )
dat
我想将一个新列附加到数据集dat,其中包含以下操作:
- 对于每一行,例如带有
id == C的第 3 行,取其余行,使其在group中的值不同于起始id,在这种情况下为 C - 按时间分组观察
t - 如果
id(在这种情况下,第3行中的idC)在列h中具有值1,则执行以下操作:将所有值相加(来自基于t的组)在x中除以y和x中的值的标准差(来自基于t的组)。如果id在列h中的值为0,则放置一个0。如果没有观察到,代码应该放置一个零。
例如,对于idA 行中的1,代码应生成0,因为在时间t == 1 的所有观察都具有group == A。对于id B 行中的2,代码应生成(11 + 16) / sd(c(11, 16, 61, 66))。
如何在dplyr 或不包括looping 的任何其他方式上执行此操作?谢谢。
数据看起来像
dat
# t id x y h group
# 1 1 A 1 51 1 B
# 2 1 B 6 56 1 A
# 3 1 C 11 61 0 A
# 4 1 D 16 66 0 A
# 5 2 A 2 52 1 A
# 6 2 B 7 57 1 B
# 7 2 C 12 62 0 C
# 8 2 D 17 67 0 D
# 9 3 A 3 53 1 A
# 10 3 B 8 58 1 B
# 11 3 C 13 63 0 D
# 12 3 D 18 68 0 C
# 13 4 A 4 54 1 A
# 14 4 B 9 59 1 D
# 15 4 C 14 64 0 C
# 16 4 D 19 69 0 A
# 17 5 A 5 55 1 A
# 18 5 B 10 60 1 C
# 19 5 C 15 65 0 C
# 20 5 D 20 70 0 B
我尝试了以下方法,但没有产生正确的结果。
dat %>%
group_by(t) %>%
mutate(new = ifelse(id != group, h * (sum(x) /map_dbl(row_number(), ~
sd(c(x[-.x], y[-.x]) ))) , 0) )
【问题讨论】:
-
如果您追求速度,我建议您使用
data.table包。 -
我需要在一个非常大的数据集上多次执行这种类型的操作。另外,我想引导整个估计过程,所以速度很重要。不幸的是,我对
dplyr知之甚少(这似乎比apply或for-loop快得多),但我对data.table知之甚少。你会如何在data.table上设置这个?
标签: r for-loop dplyr tidyverse