【问题标题】:Get the max date based on multiple columns of an R dplyr / tidyverse dataframe根据 R dplyr / tidyverse 数据框的多列获取最大日期
【发布时间】:2021-04-14 16:31:21
【问题描述】:

来自如下所示的 csv 文件:

Date Timestamp Units Name Condition Obj Param Attrib1 Atrrib2 Result
2019-07-31 2019-08-01 01:16:09 m3 n01 a1 o1 Nap TP IN 34937
2019-07-31 2019-08-01 01:16:10 m3 n01 a2 o2 Nap TP OUT 36673.09
2019-11-06 2019-11-18 20:21:06 mg/l n01 a3 o3 NO3 TP OUT 1
2019-11-06 2019-11-18 20:21:06 mg/l n01 z5 o4 BOD IO IN 220
2019-11-06 2019-11-18 20:21:06 mg/l n01 z5 o4 BOD TP IN 220
2019-11-06 2019-11-18 20:21:06 mg/l n01 z6 o1 NO2 TP OUT 0.31
2019-11-06 2019-11-18 20:21:13 mg/l n01 a11 o4 Ntot IO IN 47
2019-11-06 2019-11-18 20:21:13 mg/l n01 a11 o4 Ntot TP IN 47
2021-01-06 2021-01-07 02:15:06 m3 n01 a1 o1 Nap TP IN 17909
2021-01-06 2021-01-07 02:15:07 m3 n01 a2 o2 Nap TP OUT 19216.19

我想删除 Date 列和 Condition 列中每个值的最后一个(或最大)Timestamp 行。
结果表不应有重复的时间戳“2019-11-18 20:21:06”和“2019-11-18 20:21:13”(ConditionResult 值分别为 [z5, a11] 和 [220, 47])。

Date Timestamp Units Name Condition Obj Param Attrib1 Atrrib2 Result
2019-07-31 2019-08-01 01:16:09 m3 n01 a1 o1 Nap TP IN 34937
2019-07-31 2019-08-01 01:16:10 m3 n01 a2 o2 Nap TP OUT 36673.09
2019-11-06 2019-11-18 20:21:06 mg/l n01 a3 o3 NO3 TP OUT 1
2019-11-06 2019-11-18 20:21:06 mg/l n01 z5 o4 BOD IO IN 220
2019-11-06 2019-11-18 20:21:06 mg/l n01 z6 o1 NO2 TP OUT 0.31
2019-11-06 2019-11-18 20:21:13 mg/l n01 a11 o4 Ntot IO IN 47
2021-01-06 2021-01-07 02:15:06 m3 n01 a1 o1 Nap TP IN 17909
2021-01-06 2021-01-07 02:15:07 m3 n01 a2 o2 Nap TP OUT 19216.19

我找到了两个链接(12)来生成以下 R 脚本

library(tidyverse)
# Group per Date and Condition and filter max Timestamp
df <- read.csv("./Example.csv") %>%
    mutate(Date = as.POSIXct(Date, format = "%Y-%m-%d")) %>%
    mutate(Timestamp = as.POSIXct(Timestamp, format = "%Y-%m-%d %H:%M:%S")) %>%
    group_by(Date, Condition) %>%
    filter(Timestamp == max(Timestamp)) %>%
    distinct()
write_csv(df, file = "./ExampleResult.csv")

但我无法得到想要的结果。
这种方法有什么问题?还有其他更简单的方法吗?
谢谢!

【问题讨论】:

  • 请使用dput显示示例数据而不是图像
  • 如果您不想重复行,请使用slice_max(Timestamp, n = 1) 而不是filter
  • 谢谢 Dan Adams 和 Ronak Shah,这两个答案都能起到作用。我喜欢 Dan 建议的方法,因为在需要额外条件的其他情况下,它可能更加通用。
  • @eliasmaxil - 很高兴它有帮助。请随意accept one of the answers,这是最有帮助的

标签: r date dplyr tidyverse


【解决方案1】:

max(Timestamp) 有多个值。为了解决这个问题,我建议使用dplyr::slice_max 并设置with_ties = FALSE

这里有一些代码可以让你得到你想要的东西。

df %>% 
  mutate(Date = as.POSIXct(Date, format = "%Y-%m-%d")) %>%
  mutate(Timestamp = as.POSIXct(Timestamp, format = "%Y-%m-%d %H:%M:%S")) %>%
  group_by(Date, Condition) %>%
  slice_max(order_by = Timestamp, n = 1, with_ties = FALSE)

但根据您的应用程序,您可能希望通过向 order_by 参数提供其他变量来明确说明如何解决这些关系。

【讨论】:

    【解决方案2】:

    尝试使用以下方法:

    library(dplyr)
    
    read.csv("./Example.csv") %>%
    #df %>%
      mutate(Date = as.Date(Date), 
            Timestamp = as.POSIXct(Timestamp, format = "%Y-%m-%d %H:%M:%S")) %>%
      distinct(Date, Condition, Result, .keep_all = TRUE) -> result
    
    result
    
    #        Date           Timestamp Units Name Condition Obj Param Attrib1 Atrrib2   Result
    #1 2019-07-31 2019-08-01 01:16:09    m3  n01        a1  o1   Nap      TP      IN 34937.00
    #2 2019-07-31 2019-08-01 01:16:10    m3  n01        a2  o2   Nap      TP     OUT 36673.09
    #3 2019-11-06 2019-11-18 20:21:06  mg/l  n01        a3  o3   NO3      TP     OUT     1.00
    #4 2019-11-06 2019-11-18 20:21:06  mg/l  n01        z5  o4   BOD      IO      IN   220.00
    #5 2019-11-06 2019-11-18 20:21:06  mg/l  n01        z6  o1   NO2      TP     OUT     0.31
    #6 2019-11-06 2019-11-18 20:21:13  mg/l  n01       a11  o4  Ntot      IO      IN    47.00
    #7 2021-01-06 2021-01-07 02:15:06    m3  n01        a1  o1   Nap      TP      IN 17909.00
    #8 2021-01-06 2021-01-07 02:15:07    m3  n01        a2  o2   Nap      TP     OUT 19216.19
    

    数据

    df <- structure(list(Date = c("2019-07-31", "2019-07-31", "2019-11-06", 
    "2019-11-06", "2019-11-06", "2019-11-06", "2019-11-06", "2019-11-06", 
    "2021-01-06", "2021-01-06"), Timestamp = c("2019-08-01 01:16:09", 
    "2019-08-01 01:16:10", "2019-11-18 20:21:06", "2019-11-18 20:21:06", 
    "2019-11-18 20:21:06", "2019-11-18 20:21:06", "2019-11-18 20:21:13", 
    "2019-11-18 20:21:13", "2021-01-07 02:15:06", "2021-01-07 02:15:07"
    ), Units = c("m3", "m3", "mg/l", "mg/l", "mg/l", "mg/l", "mg/l", 
    "mg/l", "m3", "m3"), Name = c("n01", "n01", "n01", "n01", "n01", 
    "n01", "n01", "n01", "n01", "n01"), Condition = c("a1", "a2", 
    "a3", "z5", "z5", "z6", "a11", "a11", "a1", "a2"), Obj = c("o1", 
    "o2", "o3", "o4", "o4", "o1", "o4", "o4", "o1", "o2"), Param = c("Nap", 
    "Nap", "NO3", "BOD", "BOD", "NO2", "Ntot", "Ntot", "Nap", "Nap"
    ), Attrib1 = c("TP", "TP", "TP", "IO", "TP", "TP", "IO", "TP", 
    "TP", "TP"), Atrrib2 = c("IN", "OUT", "OUT", "IN", "IN", "OUT", 
    "IN", "IN", "IN", "OUT"), Result = c(34937, 36673.09, 1, 220, 
    220, 0.31, 47, 47, 17909, 19216.19)),class = "data.frame",row.names = c(NA,-10L))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-04
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 2016-01-31
      相关资源
      最近更新 更多