R 基于另一个数据帧中的信息对数据帧进行分类

R 基于另一个数据帧中的信息对数据帧进行分类,r,tidyverse,R,Tidyverse,我试图根据另一个数据帧中的信息对一个数据帧进行分类。在df1中,我有关于测量类型的信息,例如,一个罐子是否含有湿土或干土,以及在给定时间处理是否为无或ul5。在df2中,我有关于给定时间X的测量值的信息。我需要知道X的每个测量值的测量类型 我曾尝试使用full_join和fill,但两者都未能给出我想要的结果。有什么想法吗 这里是df1: df1 <- structure(list(Jar = c("Soil_dry", "Soil_dry", &q

我试图根据另一个数据帧中的信息对一个数据帧进行分类。在df1中,我有关于测量类型的信息,例如,一个罐子是否含有湿土或干土,以及在给定时间处理是否为无或ul5。在df2中,我有关于给定时间X的测量值的信息。我需要知道X的每个测量值的测量类型

我曾尝试使用full_join和fill,但两者都未能给出我想要的结果。有什么想法吗

这里是df1:

df1 <- structure(list(Jar = c("Soil_dry", "Soil_dry", "soil_wet", "soil_wet", 
"Soil_dry", "Soil_dry", "soil_wet"), Treatment = c("None", "None", 
"None", "None", "ul5", "ul5", "ul5"), Timestamp = structure(c(1608129063, 
1608129122, 1608129126, 1608129136, 1608129189, 1608129242, 1608129252
), class = c("POSIXct", "POSIXt"), tzone = "UTC")), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -7L), spec = structure(list(
    cols = list(Jar = structure(list(), class = c("collector_character", 
    "collector")), Treatment = structure(list(), class = c("collector_character", 
    "collector")), Timestamp = structure(list(format = ""), class = c("collector_datetime", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))
df2:

所需数据:

desired_data <- structure(list(X = c(5, 3, 34, 4, 65, 9, 7), Timestamp = structure(c(1608129064, 
1608129122, 1608129125, 1608129133, 1608129188, 1608129240, 1608129243
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Jar = c("Soil_dry", 
"Soil_dry", "Soil_dry", "soil_wet", "soil_wet", "Soil_dry", "Soil_dry"
), Treatment = c("None", "None", "None", "None", "None", "ul5", 
"ul5")), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -7L), spec = structure(list(cols = list(
    X = structure(list(), class = c("collector_double", "collector"
    )), Timestamp = structure(list(format = ""), class = c("collector_datetime", 
    "collector")), Jar = structure(list(), class = c("collector_character", 
    "collector")), Treatment = structure(list(), class = c("collector_character", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), skip = 1), class = "col_spec"))
尝试数据。表的滚动联接

library(data.table)
setDT(df1)
setDT(df2)
df1[df2, roll = "nearest", on = "Timestamp"]
如果要确保所选行始终大于df2中的时间戳:


左转怎么样?像这样:左关节2,左关节1%>%fillJar,治疗。谢谢你的建议@CainãMaxCouto Silva,我觉得效果很好!谢谢你的建议@Ronak Shah!我想知道你的解决方案是否适用于所有情况,因为我忘了在我最初的问题中完整地描述情况。假设在2020-12-16 14:38:02有一个X值。我猜这个测量值会被归类为土壤湿/无,因为它最接近第10行,土壤湿,无,2020-12-16 14:38:03。实际上应该是土壤干燥,因为只有14:38:03之后的测量才应归类为土壤湿润。是的,data.table rolling join采用最接近的匹配。对于您的具体情况,我认为更新后的答案应该会有所帮助,因为我们只选择df2中时间戳之后出现的值。Hm,看起来X值与更新后的解决方案不一致X值如何?你能把这个例子缩短5行吗?这样比较容易检查。您还可以更新您的预期输出。该解决方案进行左连接,因此它依赖于两个数据帧中某处时间戳的精确匹配这一事实。如果没有精确匹配,则返回所有NA。此外,如果仔细查看解决方案,它不会始终返回正确的时间戳。例如,如果您在2020-12-16 14:38:03有一个精确匹配,并且在2020-12-16 14:38:05有另一个条目需要与2020-12-16 14:38:06匹配,那么它的值将为2020-12-16 14:38:03,而不是2020-12-16 14:38:05。
library(data.table)
setDT(df1)
setDT(df2)
df1[df2, roll = "nearest", on = "Timestamp"]
library(dplyr)

tidyr::crossing(df1 %>%rename(Timestamp1 = Timestamp), 
                df2 %>% rename(Timestamp2 = Timestamp)) %>%
  mutate(diff = as.numeric(Timestamp2 - Timestamp1)) %>%
  filter(diff > 0) %>% 
  arrange(Jar, Timestamp2, diff) %>%
  group_by(Timestamp2) %>%
  slice(1L) %>%
  ungroup %>%
  arrange(Timestamp2) %>%
  select(-diff)

#  Jar      Treatment Timestamp1              X Timestamp2         
#  <chr>    <chr>     <dttm>              <dbl> <dttm>             
#1 Soil_dry None      2020-12-16 14:31:03     5 2020-12-16 14:31:04
#2 Soil_dry None      2020-12-16 14:31:03     3 2020-12-16 14:32:02
#3 Soil_dry None      2020-12-16 14:32:02    34 2020-12-16 14:32:05
#4 Soil_dry None      2020-12-16 14:32:02     4 2020-12-16 14:32:13
#5 Soil_dry None      2020-12-16 14:32:02    65 2020-12-16 14:33:08
#6 Soil_dry ul5       2020-12-16 14:33:09     9 2020-12-16 14:34:00
#7 Soil_dry ul5       2020-12-16 14:34:02     7 2020-12-16 14:34:03