【问题标题】:Subsetting a dataframe based on daily maxima根据每日最大值对数据框进行子集
【发布时间】:2012-06-19 21:36:25
【问题描述】:

我有一个带有日期/时间列以及与该日期/时间关联的值的 excel csv。我正在尝试编写一个将通过这种格式的脚本(见下文),并找到 1)每天的最大值,以及 2)当天发生最大值的时间。最好 R 会在一个新的数据框中将这两个值都返回给我。

数据看起来像这样:

         V1    V2 V3
1  5/1/2012  3:00  1
2  5/1/2012  6:00  2
3  5/1/2012  9:00  5
4  5/1/2012 12:00  3
5  5/1/2012 15:00  6
6  5/1/2012 18:00  2
7  5/1/2012 21:00  1
8  5/2/2012  0:00  2
9  5/2/2012  3:00  3
10 5/2/2012  6:00  6
11 5/2/2012  9:00  4
12 5/2/2012 12:00  6
13 5/2/2012 15:00  7
14 5/2/2012 18:00  9
15 5/2/2012 21:00  1

所以我设想的函数会返回:

1 5/1/2012 15:00 6
2 5/2/2012 18:00 9

有什么想法吗?

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    使用 plyr 包的解决方案,我发现它非常适合此类问题。

    dat.str <- '         V1    V2 V3
    1  5/1/2012  3:00  1
    2  5/1/2012  6:00  2
    3  5/1/2012  9:00  5
    4  5/1/2012 12:00  3
    5  5/1/2012 15:00  6
    6  5/1/2012 18:00  2
    7  5/1/2012 21:00  1
    8  5/2/2012  0:00  2
    9  5/2/2012  3:00  3
    10 5/2/2012  6:00  6
    11 5/2/2012  9:00  4
    12 5/2/2012 12:00  6
    13 5/2/2012 15:00  7
    14 5/2/2012 18:00  9
    15 5/2/2012 21:00  1'
    
    dat <- read.table(textConnection(dat.str), row.names=1, header=TRUE)
    
    library(plyr)
    ddply(dat, .(V1), function(x){
       x[which.max(x$V3), ]
    })
    

    【讨论】:

      【解决方案2】:

      如果你正在处理时间序列数据,我建议你使用像zooxts这样的时间序列类

      dat <- read.table(text="         V1    V2 V3
      1  5/1/2012  3:00  1
      2  5/1/2012  6:00  2
      3  5/1/2012  9:00  5
      4  5/1/2012 12:00  3
      5  5/1/2012 15:00  6
      6  5/1/2012 18:00  2
      7  5/1/2012 21:00  1
      8  5/2/2012  0:00  2
      9  5/2/2012  3:00  3
      10 5/2/2012  6:00  6
      11 5/2/2012  9:00  4
      12 5/2/2012 12:00  6
      13 5/2/2012 15:00  7
      14 5/2/2012 18:00  9
      15 5/2/2012 21:00  1", row.names=1, header=TRUE)
      
      require("xts")
      # create an xts object
      xobj <- xts(dat[, 3], order.by=as.POSIXct(paste(dat[, 1], dat[, 2]), format="%m/%d/%Y %H:%M"))
      

      如果您只是想获得每日最大值,并且可以使用一天中的最后一个时间作为索引,您可以使用 apply.daily

      apply.daily(xobj, max)
      #                    [,1]
      #2012-05-01 21:00:00    6
      #2012-05-02 21:00:00    9
      

      要保留它发生的时间戳,您可以这样做

      do.call(rbind, lapply(split(xobj, "days"), function(x) x[which.max(x), ]))
      #                    [,1]
      2012-05-01 15:00:00    6
      2012-05-02 18:00:00    9
      

      split(xobj, "days") 在每个元素中创建一个包含一天数据的列表。

      lapply 对每一天应用一个函数;在这种情况下,该函数只返回每天的max 观察值。 lapply 调用将返回 xts 对象的 list。把它变回 单个 xts 对象,使用do.call

      do.call(rbind, X) 使用列表的每个元素构造对 rbind 的调用。相当于rbind(X[[1]], X[[2]], ..., X[[n]])

      【讨论】:

        【解决方案3】:

        对于另一种选择,您可以使用data.table:

        dat_table <- data.table(dat)
        
        dat_table [ , list(is_max = V3==max(V3), V2, V3), by= 'V1'][which(is_max),][,is_max :=NULL]
        

        编辑根据@MattDowle 的评论

        dat_table[, .SD[which.max(V3)], by=V1]
        

        对于更简单的data.table 解决方案。

        【讨论】:

        • 这是一个有趣的解决方案,我喜欢复合。但在这种情况下,有一个更简单的方法:DT[,.SD[which.max(V3)],by=V1]
        • 简单得多。我认为必须有。
        【解决方案4】:

        给你:

        dat.str <- '         V1    V2 V3
        1  5/1/2012  3:00  1
        2  5/1/2012  6:00  2
        3  5/1/2012  9:00  5
        4  5/1/2012 12:00  3
        5  5/1/2012 15:00  6
        6  5/1/2012 18:00  2
        7  5/1/2012 21:00  1
        8  5/2/2012  0:00  2
        9  5/2/2012  3:00  3
        10 5/2/2012  6:00  6
        11 5/2/2012  9:00  4
        12 5/2/2012 12:00  6
        13 5/2/2012 15:00  7
        14 5/2/2012 18:00  9
        15 5/2/2012 21:00  1'
        
        dat <- read.table(textConnection(dat.str), row.names=1, header=TRUE)
        
        do.call(rbind, 
                by(dat, INDICES=dat$V1, FUN=function(x) tail(x[order(x$V3), ], 1)))
        

        【讨论】:

        • 谢谢,非常适合我提供的示例。您能快速解释一下您使用的 ' 符号吗?
        • 我是否需要包含它才能使用 textConnection 功能?
        • textConnection 接受一个字符串并返回一个到它的连接。
        猜你喜欢
        • 2020-10-17
        • 2013-03-17
        • 2019-02-16
        • 2013-08-15
        • 1970-01-01
        • 2019-10-16
        • 2021-06-14
        • 2020-04-20
        • 2020-08-19
        相关资源
        最近更新 更多