【问题标题】:How to subset data frame based on date differences?如何根据日期差异对数据框进行子集化?
【发布时间】:2021-06-14 11:09:34
【问题描述】:

我有两个数据框,我想对 df2 中的特定行进行子集化。这是df1和df2:

df1:
   Sdate    columnA    D
2020-05-14    DD       1
2020-05-14    FF       5
2020-05-14    EE       6
2020-05-14    GG       7

df2:
   Sdate      ColA     C
2020-04-13    NN       1
2020-04-13    XX       1
2020-04-14    VV       5
2020-04-15    DD       6
2020-04-16    AA       7

以下是获得最终输出的步骤:

  1. 我需要计算 df1 的 [1,1](即“2020-05-14”)和 df2 的 [1,1](即“2020-04-13”)之间的日期差异
  2. 我需要确定差异是否大于 10 天。
  3. 最后,如果大于 10 天,我想删除 df2 中日期最早的行。因为 2020-04-13 是 df2 中最早的日期,所以我想删除 df2 的前两个低点。

“2020-05-14”-“2020-04-13”是31。因此,我的df2最终输出应该是

   Sdate     ColA      C
2020-04-14    VV       5
2020-04-15    DD       6
2020-04-16    AA       7

我尝试了以下代码:

df2 <- ifelse(as.numeric(as.Date(as.character(df1[1,1]), format="%Y-%m-%d")-
                         as.Date(as.character(df2[1,1]), format="%Y-%m-%d"))>10,
                       subset(df2, Sdate!= df2[1,1]),print("Pass"))

我将这段代码分成三部分进行了单独测试,它们运行良好。但它不在上面的组合代码中。 df2 刚刚随代码一起消失了。

我应该改变什么才能得到我想要的?

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以为此使用 dplyr。我提供了一种方法,您无需比较第一行,只需取最小值即可。

    library(dplyr)
    
    new_df <- df2 %>% 
      mutate(
        isOldest = Sdate == min(Sdate),
        deleteOldest = as.integer(min(df1$Sdate) - min(Sdate)) > 10
      ) %>% 
      filter(!(isOldest & deleteOldest))
    

    如果您实际上只需要比较第一行:

    new_df <- df2 %>% 
      mutate(
        isOldest = Sdate == df2$Sdate[1],
        deleteOldest = as.integer(df1$Sdate[1] - df2$Sdate[1]) > 10
      ) %>% 
      filter(!(isOldest & deleteOldest))
    

    希望这是您所需要的。下面的数据框。

    df1 <- data.frame(
      Sdate = as.Date('2020-05-14'),
      columnA = c('DD', 'FF', 'EE', 'GG'),
      D = c(1, 5, 6, 7),
      stringsAsFactors = FALSE
    )
    
    df2 <- data.frame(
      Sdate = as.Date(c(rep('2020-04-13', 2), '2020-04-14', '2020-04-15',' 2020-04-16')),
      colA = c('NN', 'XX', 'VV', 'DD', 'AA'),
      C = c(1, 1, 5, 6, 7),
      stringsAsFactors = FALSE
    )
    

    【讨论】:

    • 非常感谢,但我收到一个错误:mutate() 输入问题deleteOldest。 x 是二进制的非数字因子。我认为我的原始数据框在 Sdate 列中具有不同的日期格式。
    • 您是如何读取数据帧的?我明确地将 stringsAsFactors 设置为 false。也许这可以解释差异?
    • 嘿,当我像原来的问题一样编辑时,它可以工作: deleteOldest = as.numeric(as.Date(as.character(min(Prv$Sdate)),format="%Y-%m -%d") - as.Date(as.character((Sdate)),format="%Y-%m-%d")) > 10 你知道为什么会这样吗?还是谢谢你!
    • 完美运行。我建议尝试class(Prv$Sdate)。我怀疑,在你的情况下,它说的是因素。有一个帖子here 值得一看。
    猜你喜欢
    • 2020-10-17
    • 1970-01-01
    • 2019-12-28
    • 2013-08-15
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多