浪费了将近一天后,我正在寻求帮助.我有一个大数据帧(bdf)和一个小数据帧(sdf).我想将变量z添加到bdf,具体取决于sdf $ y的值(它随时间变量的变化而变化).
这是一个可重复的例子:
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
Run Code Online (Sandbox Code Playgroud)
我想在bdf中使用以下sdf $ y值创建变量z:
对于行,其中bdf $ tb的范围从第一个bdf $ tb到sdf $ ts的第一个和第二个值之间的中间值.在这个简单的例子中,这是dbf的第1行到第3行的情况,其时间bdf $ tb低于"2013-05-23 12:00:00 GMT".
-0.1对于行,其中bdf $ tb的范围从sdf $ ts的第1和第2值之间的中间到sdf $ ts的第2和第3值之间的中间.在这个简单的例子中,这是dbf的第4行和第5行的情况,在"2013-05-23 12:00:00 GMT"和"2013-05-27 12:00:00 GMT"之间的时间为bdf $ tb .
对于所有行,其中bdf $ tb的范围是从sdf $ ts的第2和第3值到bdf $ tb的最后一个值的中间值.在这个简单的例子中,这是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
Run Code Online (Sandbox Code Playgroud)
我无法成功使用dplyr :: mutate并且无处使用循环...任何帮助都将非常感激.我希望我清楚地将这个问题描述为坚持礼仪(这是我的第一个问题).
下面是一个使用的解决方案data.table的滚动加入:
require(data.table)
setkey(setDT(sdf), ts)
sdf[bdf, roll = "nearest"]
# ts y
# 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
Run Code Online (Sandbox Code Playgroud)
setDT通过引用将data.frame转换为data.table .
setkey通过提供的列按递增顺序对data.table 进行排序,并将这些列标记为键列(以便我们稍后可以在这些键列上连接.
在data.table中,x[i]当data.table时执行连接i.如果您还不熟悉,我会推荐您回答这个问题来了解data.table连接.
x[i]执行等连接.也就是说,它x为每一行中找到匹配的行索引i,然后从中提取这些行x以返回连接结果以及相应的行i.如果连续i没有找到匹配行索引x,该行不得不NA为x默认.
但是,x[i, roll = .]执行滚动连接.当没有匹配时,最后一个观察结果是前进(roll = TRUE或-Inf),或者下一个观察结果可以向后运送(roll = Inf),或者滚动到最近的值(roll = "nearest").在这种情况下,您需要roll = "nearest"IIUC.
HTH
现在看来这绝对没有必要,但在基础上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]
}
Run Code Online (Sandbox Code Playgroud)
虽然有点笨拙,但它的优点是清晰,可以轻松适应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
Run Code Online (Sandbox Code Playgroud)