【问题标题】:Conditional operations between factor level pairs因子水平对之间的条件运算
【发布时间】:2021-08-29 19:56:37
【问题描述】:

我有一个数据框 (df1),其中包含 Start 次和 End 次,用于观察不同的 IDs:

df <- structure(list(ID = 1:4, Start = c("2021-05-12 13:22:00", "2021-05-12 13:25:00", "2021-05-12 13:30:00", "2021-05-12 13:42:00"), 
End = c("2021-05-13 8:15:00", "2021-05-13 8:17:00", "2021-05-13 8:19:00", "2021-05-13 8:12:00")), 
class = "data.frame", row.names = c(NA, 
-4L))

我想创建一个新的数据框,显示Start 的最新时间和End 的最早时间,以便在ID 的级别之间进行每个可能的成对比较。

我能够通过创建一个名为 ID2 的重复列 ID 来完成此操作,使用 dplyr::expand 扩展它们,并将其保存在一个名为 Pairs 的对象中:

library(dplyr)
df$ID2 <- df$ID
Pairs <- 
  df%>%
  expand(ID, ID2)

创建两个新对象ab,分别存储每次比较的StartEnd时间,然后将它们组合成df2

a <- left_join(df, Pairs, by = 'ID')%>%
  rename(StartID1 = Start, EndID1 = End, ID2 = ID2.y)%>%
  select(-ID2.x)
b <- left_join(Pairs, df, by = "ID2")%>%
  rename(StartID2 = Start, EndID2 = End)%>%
  select(ID2, StartID2, EndID2)
df2 <- cbind(a,b)
df2 <- df2[,-4]

最后使用dplyr::if_else 为每个比较找到LatestStart 时间和EarliestEnd 时间:

df2 <- 
  df2%>%
  mutate(LatestStart = if_else(StartID1 > StartID2, StartID1, StartID2),
         EarliestEnd = if_else(EndID1 > EndID2, EndID2, EndID1))

这似乎是一项非常简单的任务,有没有更简洁的方法可以从df1 实现这一目标,而无需创建所有这些额外的对象?

【问题讨论】:

    标签: r if-statement dplyr conditional-statements


    【解决方案1】:

    对于此类计算,outer 通常会派上用场:

    df %>%
      mutate(across(c("Start", "End"), lubridate::ymd_hms)) %>%
      {
        data.frame(
          ID1 = rep(.$ID, each = nrow(.)),
          ID2 = rep(.$ID, nrow(.)),
          LatestStart = outer(.$Start, .$Start, pmax),
          LatestEnd = outer(.$End, .$End, pmin)
        )
      }
    

    【讨论】:

    • 当我运行这段代码时,我得到Error in [.default(xj, i, , drop = FALSE) : subscript out of bounds
    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多