R中2个数据帧的时间值之间的条件合并

时间:2018-07-01 15:49:56

标签: r datetime merge

我有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,但是我无法使其正常工作。

2 个答案:

答案 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