我浪费了将近一天后寻求帮助。我有一个大数据框(bdf)和一个小数据框(sdf)。我想根据sdf $ y的值将变量z添加到bdf(随时间变量的变化而变化)。
这是一个可重现的示例:
bdf <- data.frame(tb = seq(as.POSIXct("2013-05-19 17:11:22 GMT", tz="GMT"), by=5624*24, length.out=10))
bdf
tb
1 2013-05-19 17:11:22
2 2013-05-21 06:40:58
3 2013-05-22 20:10:34
4 2013-05-24 09:40:10
5 2013-05-25 23:09:46
6 2013-05-27 12:39:22
7 2013-05-29 02:08:58
8 2013-05-30 15:38:34
9 2013-06-01 05:08:10
10 2013-06-02 18:37:46
sdf <- data.frame(ts = as.POSIXct(c("2013-05-22", "2013-05-25", "2013-05-30"), tz="GMT"), y = c(0.2, -0.1, 0.3))
> sdf
ts y
1 2013-05-22 0.2
2 2013-05-25 -0.1
3 2013-05-30 0.3
我想使用以下sdf $ y值在bdf中创建变量z:
对于bdf $ tb从第一个bdf $ tb值到sdf $ ts的第一个值与第二个值之间的中间值的行,为0.2。在此简单示例中,dbf的第1到3行的时间为bdf $ tb低于“ 2013-05-23 12:00:00 GMT”的情况。
-0.1对于bdf $ tb从sdf $ ts的第一和第二值之间的中间到sdf $ ts的第二和第三值之间的中间的行。在此简单示例中,dbf的第4行和第5行就是这种情况,在“ 2013-05-23 12:00:00 GMT”和“ 2013-05-27 12:00:00 GMT”之间的时间为bdf $ tb 。
对于bdf $ tb从sdf $ ts的第二个和第三个值之间的中间值到bdf $ tb的最后一个值的中间范围的所有行,该值为0.3。在此简单示例中,情况是dbf的行1至6至10的时间大于“ 2013-05-23 12:00:00 GMT”的时间。
因此,最后,大数据框bdf应该如下所示:
tb z
1 2013-05-19 17:11:22 0.2
2 2013-05-21 06:40:58 0.2
3 2013-05-22 20:10:34 0.2
4 2013-05-24 09:40:10 -0.1
5 2013-05-25 23:09:46 -0.1
6 2013-05-27 12:39:22 0.3
7 2013-05-29 02:08:58 0.3
8 2013-05-30 15:38:34 0.3
9 2013-06-01 05:08:10 0.3
10 2013-06-02 18:37:46 0.3
我无法成功使用dplyr :: mutate,并且无法使用循环...任何帮助将不胜感激。我希望我清楚地将这个问题描述为遵守礼节的问题(这是我的第一个问题)。
最佳答案
现在看来绝对没有必要,但是在基本R
中
bdf$z <- numeric(nrow(bdf))
for(i in seq_along(bdf$z)){
ind <- which.min(abs(bdf$tb[i] - sdf$ts))
bdf$z[i] <- sdf$y[ind]
}
它虽然笨拙,但在清晰度方面具有优势,可轻松适应
dplyr
library(dplyr)
bdf %>% rowwise() %>%
mutate(z= sdf$y[which.min(abs(as.numeric(tb)-as.numeric(sdf$ts)))])
#Source: local data frame [10 x 2]
#Groups: <by row>
# tb z
#1 2013-05-19 17:11:22 0.2
#2 2013-05-21 06:40:58 0.2
#3 2013-05-22 20:10:34 0.2
#4 2013-05-24 09:40:10 -0.1
#5 2013-05-25 23:09:46 -0.1
#6 2013-05-27 12:39:22 0.3
#7 2013-05-29 02:08:58 0.3
#8 2013-05-30 15:38:34 0.3
#9 2013-06-01 05:08:10 0.3
#10 2013-06-02 18:37:46 0.3