【问题标题】:r ifelse condition for the calculation on multiple dataframesr ifelse 计算多个数据帧的条件
【发布时间】:2018-12-07 21:42:15
【问题描述】:

我有 3 个数据框,df1 = 时间间隔,df2 = ID 列表,df3 = 具有关联日期的 ID 列表。

df1 <- structure(list(season = structure(c(2L, 1L), .Label = c("summer", 
    "winter"), class = "factor"), mindate = structure(c(1420088400, 
    1433131200), class = c("POSIXct", "POSIXt")), maxdate = structure(c(1433131140, 
    1448945940), class = c("POSIXct", "POSIXt")), diff = structure(c(150.957638888889, 
    183.040972222222), units = "days", class = "difftime")), .Names = c("season", 
    "mindate", "maxdate", "diff"), row.names = c(NA, -2L), class = "data.frame")

df2 <- structure(list(ID = c(23796, 23796, 23796)), .Names = "ID", row.names = c(NA, 
    -3L), class = "data.frame")

df3 <- structure(list(ID = c("23796", "123456", "12134"), time = structure(c(1420909920, 
1444504500, 1444504500), class = c("POSIXct", "POSIXt"), tzone = "US/Eastern")), .Names = c("ID", 
"time"), row.names = c(NA, -3L), class = "data.frame")

如果 df2$ID == df3$ID,代码应该进行比较。如果为真,并且如果 df3$time >= df1$mindate 并且 df3$time

df1$result <- ifelse(df2[1,1] == df3[1,1] & df3[1,2] >= df1$mindate & df3[1,2] <= df1$maxdate, 
                     difftime(df1$maxdate,df3[1,2],units="days"),
                     difftime(df1$maxdate,df1$mindate,units="days")

编辑:所需的输出是(删除 df2 的最后一行时):

 season    mindate             maxdate          diff   result
1 winter 2015-01-01 2015-05-31 23:59:00 150.9576 days 141.9576
2 summer 2015-06-01 2015-11-30 23:59:00 183.0410 days 183.0410

有什么想法吗?我不知道如何合并 dfs 以使它们具有相同的长度。请注意,df2 可以是任意行长,并且不会影响代码。当 df1 和 df3 的行数不同时会出现问题。

【问题讨论】:

  • 能否添加您想要的输出?

标签: r if-statement dataframe


【解决方案1】:

&gt;&lt; 是矢量化的:

transform(df1,result=ifelse(df3$ID%in%df2$ID & df3$time>mindate & df3$time <maxdate, difftime(maxdate,df3$time),difftime(maxdate,mindate)))
  season             mindate             maxdate          diff   result
1 winter 2014-12-31 21:00:00 2015-05-31 20:59:00 150.9576 days 141.9576
2 summer 2015-05-31 21:00:00 2015-11-30 20:59:00 183.0410 days 183.0410

您还可以使用data.table 库中的between 函数

library(data.table)
transform(df1,result=ifelse(df3$ID%in%df2$ID&df3$time%between%df1[2:3],
               difftime(maxdate,df3$time),difftime(maxdate,mindate)))

  season             mindate             maxdate          diff   result
1 winter 2014-12-31 21:00:00 2015-05-31 20:59:00 150.9576 days 141.9576
2 summer 2015-05-31 21:00:00 2015-11-30 20:59:00 183.0410 days 183.0410

【讨论】:

  • 解决方案适用于这个特定的示例。但是当我将它们(例如,第二个)应用于我的特殊需要时,我得到以下错误/警告返回: ifelse 错误(ind$elasmo %in% df$elasmo & ind$Date.and.time %between% :缺少参数“no”,没有默认值另外:警告消息:1:在 >=.default(x, lower) 中:较长的对象长度不是较短对象长度的倍数 2:在
  • @FlyingDutch 您首先需要的是查看两个 dfs 应该如何具有相同的行,因为使用的逻辑是 df1 的第一行与 df3 的第一行等......或者你需要一个 id 才能将两者合并。 ifelse 语句也继续到下一行。看第一个代码,你会看到 tgat ifelse 语句很长
  • 然而,尽管能够理解代码,但我似乎很难摆脱不同 nbr 行的错误。警告很好,仍然会产生正确的结果。有什么建议吗?
  • @FlyingDutch 比如说 data1 有 10 行,data3 有 6 行,那么这些行是如何相关的? data1 的第 1 行映射到 data3 的哪一行?应该有一种方法可以映射两个数据框行。例如,表示第 1 行的 id 映射到第 1 行,甚至 df1 的第 2 行映射到 df3 的第 2 行或映射到不同的行等。在这种情况下,您可以合并两个数据帧以具有相同的行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2017-02-14
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多