根据另一个数据帧在R数据帧中创建变量
我浪费了将近一天的时间,现在正在寻求帮助。我有一个大数据帧(bdf)和一个小数据帧(sdf)。我想根据sdf$y的值(它随时间变量的变化而变化),将变量z添加到bdf中 以下是一个可复制的示例:根据另一个数据帧在R数据帧中创建变量,r,R,我浪费了将近一天的时间,现在正在寻求帮助。我有一个大数据帧(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:2
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
我无法成功地使用dplyr::mutate,而使用循环却一事无成。。。任何帮助都将不胜感激。我希望我清楚地描述了遵守礼仪的问题(这是我的第一个问题)。以下是我的方法:
library(zoo)
m <- c(rollmean(as.POSIXct(sdf$ts), 2), Inf)
transform(bdf, z = sdf$y[sapply(tb, function(x) which.max(x < m))])
# 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
图书馆(动物园)
编辑注释:我最初得到的结果与您的略有不同,我现在认为这与我对R difftime对象缺乏理解有关。POSIXt
对象中的时区对我来说仍然是个谜,但我现在看到,当我强制一个“difftime”对象为“numeric”时,我得到的值是“days”
findInterval
函数作为索引创建函数非常有用,该函数映射一个值向量,其中一个值向量具有多个相邻的非重叠间隔。实际上,只有两个时间点分成三个时间间隔
bdf$z <- c(0.2,-0.1,0.3)[findInterval(bdf$tb,
c(-Inf,
sdf$ts[2] - 0.5*as.numeric(difftime(sdf$ts[2], sdf$ts[1], units="secs")),
sdf$ts[3] - 0.5*as.numeric(difftime(sdf$ts[3], sdf$ts[2],units="sec")),
Inf))]
> 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
bdf$z bdf
tbz
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
我还检查了findIntervals中的间隔是否在其右侧而不是左侧(默认值)关闭是否会影响我的结果,并且没有发现任何差异 下面是一个使用数据的解决方案。表的滚动联接:
setDT
通过引用将data.frame转换为data.table
setkey
按提供的列按引用的递增顺序对data.table进行排序,并将这些列标记为键列(以便我们以后可以连接这些键列)
- 在data.table中,当
i
是data.table时,x[i]
执行联接。如果您还不熟悉data.table联接,我会让您参考
x[i]
执行相等联接。也就是说,它在x
中为i
中的每一行查找匹配的行索引,然后从x
中提取这些行,以返回联接结果以及i
中相应的行。如果i
中的一行在x
中未找到匹配的行索引,则该行将返回联接结果默认情况下,x的NA
但是,x[i,roll=.]
执行滚动联接。当不匹配时,要么将上一个观测值向前推进(roll=TRUE
或-Inf
),要么将下一个观测值向后推进(roll=Inf
),要么滚动到最近的值(roll=“nearest”
).在这种情况下,您需要roll=“nearest”
IIUC
HTH这现在似乎完全没有必要,但在baseR
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]
}
听起来像是连接到包数据中最近的值。表可能roll=“nearest”
但我没有这方面的经验,我很好奇在dplyr
中使用rollmean
是否可行。它可以在我的方法中填充findInterval
向量,并回避我在difftime
中遇到的问题。第二个选项是我最喜欢的。它是最简单的解决方案不需要任何额外的程序包,而且非常简短。误解了投票系统,希望投票支持此答复
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
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]
}
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