根据另一个数据帧在R数据帧中创建变量

gat*_*uso 6 r

浪费了将近一天后,我正在寻求帮助.我有一个大数据帧(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并且无处使用循环...任何帮助都将非常感激.我希望我清楚地将这个问题描述为坚持礼仪(这是我的第一个问题).

Aru*_*run 8

下面是一个使用的解决方案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,该行不得不NAx默认.

    但是,x[i, roll = .]执行滚动连接.当没有匹配时,最后一个观察结果是前进(roll = TRUE-Inf),或者下一个观察结果可以向后运送(roll = Inf),或者滚动到最近的值(roll = "nearest").在这种情况下,您需要roll = "nearest"IIUC.

HTH


Kha*_*haa 3

现在看来这绝对没有必要,但在基础上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)