我有2个具有不同结构的数据框。第一个包含来自连续样本和对几个样品进行重复分析的数据(多行包含每次测量的时间和值),第二个报告样品ID以及测量的开始和结束时间。
##example
df.analysis <- data.frame(var= rnorm(321,mean=50),
time= seq(strptime("2018-1-1 0:0:0","%Y-%m-%d %H:%M:%S"), strptime("2018-1-1 8:0:0","%Y-%m-%d %H:%M:%S"), by= 90))
df.sample <- data.frame(sample= rep_len(1:8, 30),
start=seq(strptime("2018-1-1 0:0:0","%Y-%m-%d %H:%M:%S"), strptime("2018-1-1 7:45:0","%Y-%m-%d %H:%M:%S"),length.out=30),
end=seq(strptime("2018-1-1 0:15:0","%Y-%m-%d %H:%M:%S"), strptime("2018-1-1 8:0:0","%Y-%m-%d %H:%M:%S"),length.out=30))
我应该插入与每个测量值相对应的样品ID,请注意并非所有测量都对应于一个样品。 我尝试使用以下代码,但是它不起作用,因为现在它将第一个数据库中的行与第二个数据库中的对应行进行比较。虽然我需要将第一个数据库中的每一行与第二个数据库中的所有行进行比较
if df.analysis$time >df.sample[,"start"] & df.analysis$time < df.sample[,"end"] {
df.analysis$sample <- df.sample$sample
}
我本以为使用for
循环或lapply
,但是我无法使其正常工作。
答案 0 :(得分:2)
我们可以使用非等额联接
library(data.table)
setDT(df.analysis)[df.sample, sample := sample, on = .(time > start, time <end)]
答案 1 :(得分:2)
使用sqldf
包的一个选项可以通过使inner join
然后是left outer join
来实现:
library(sqldf)
sqldf("select analysis.*, matchedSample.sample from
'df.analysis' analysis
left outer join
(select sample.sample, analysis.time
from 'df.sample' sample,'df.analysis' analysis
where analysis.time > sample.start
and analysis.time < sample.end) matchedSample on
analysis.time = matchedSample.time")
# var time sample
# 1 49.41763 2018-01-01 00:00:00 NA
# 2 50.20399 2018-01-01 00:01:30 1
# 3 48.80242 2018-01-01 00:03:00 1
# 4 50.56982 2018-01-01 00:04:30 1
# 5 50.08948 2018-01-01 00:06:00 1
# 6 50.32223 2018-01-01 00:07:30 1
# 7 49.60842 2018-01-01 00:09:00 1
# 8 50.82316 2018-01-01 00:10:30 1
# ....
# .... 313 more rows