【问题标题】:First highest value in each frame in a list and add into a new column列表中每个帧中的第一个最大值并添加到新列中
【发布时间】:2017-05-01 14:46:04
【问题描述】:

我试图找出“价格”每天第一次高于另一个名为“dayhigh”的值。

我在将这个结果放入时间序列对象时遇到了问题,所以我只是将 POSIXlt 类用于日期时间,而参考日期在 Date 类中。 示例数据位于名为“示例”的框架中:

day,datetime,price,dayhigh
2016-09-01,2016-09-01 15:00:00,1.11912,1.11990
2016-09-01,2016-09-01 15:00:00,1.13000,1.11990
2016-09-01,2016-09-01 15:00:01,1.11911,1.11990
2016-09-05,2016-09-05 15:00:00,1.11436,1.11823
2016-09-05,2016-09-05 15:00:01,1.11436,1.11823
2016-09-05,2016-09-05 15:00:01,1.11900,1.11823
2016-09-05,2016-09-05 15:00:01,1.11436,1.11823
2016-09-06,2016-09-06 15:00:00,1.12383,1.12557
2016-09-06,2016-09-06 15:00:00,1.12382,1.12557
2016-09-06,2016-09-06 15:00:00,1.12382,1.12557
2016-09-06,2016-09-06 15:00:00,1.12384,1.12557
2016-09-06,2016-09-06 15:00:00,1.12384,1.12557
2016-09-06,2016-09-06 15:00:00,1.12558,1.12557
2016-09-06,2016-09-06 15:00:01,1.12559,1.12557

df = data.frame(
  day = c("2016-09-01", "2016-09-01", "2016-09-01", "2016-09-05", "2016-09-05", 
          "2016-09-05", "2016-09-05", "2016-09-06", "2016-09-06", "2016-09-06", 
          "2016-09-06", "2016-09-06", "2016-09-06", "2016-09-06"),
  datetime = c("2016-09-01 15:00:00", "2016-09-01 15:00:00", "2016-09-01 15:00:01", 
               "2016-09-05 15:00:00", "2016-09-05 15:00:01", "2016-09-05 15:00:01",
               "2016-09-05 15:00:01", "2016-09-06 15:00:00", "2016-09-06 15:00:00", 
               "2016-09-06 15:00:00", "2016-09-06 15:00:00", "2016-09-06 15:00:00", 
               "2016-09-06 15:00:00", "2016-09-06 15:00:01"),
  price = c(1.11912, 1.13, 1.11911, 1.11436, 1.11436, 1.119, 1.11436,
            1.12383, 1.12382, 1.12382, 1.12384, 1.12384, 1.12558, 1.12559), 
  dayhigh = c(1.1199, 1.1199, 1.1199, 1.11823, 1.11823, 1.11823, 1.11823,
              1.12557, 1.12557, 1.12557, 1.12557, 1.12557, 1.12557, 1.12557)
)

我的一个想法是将帧按天拆分为帧列表:

exlist <- split(example, as.Date(example$day))

这会返回一个对象列表。

我想要做的是在列表中的每个框架对象上使用which.max,并将“TRUE”添加到每个框架中的新列中,用于出现当天第一个高点的行。当天的第一个高点定义为每天的第一个price &gt; dayhigh

从那里我可以连接回单个帧并执行进一步分析。

【问题讨论】:

  • @Frank:标签dataframe, data.table, max, which都是相关的,请停止恢复它们。

标签: r dataframe max


【解决方案1】:

我有另一个基于data.table 的解决方案。

library(data.table)
setDT(example)
example[, first.high:= (.I == .I[which.max(price>dayhigh)]), by=day ]

【讨论】:

    【解决方案2】:

    无需完成所有工作,您可以使用data.table 一步完成:

    library(data.table)
    setDT(df)
    df[ , first_high := (seq_len(.N) == which(price > dayhigh)[1]), by = day ]
    
    df
    #           day            datetime   price dayhigh first_high
    # 1: 2016-09-01 2016-09-01 15:00:00 1.11912 1.11990      FALSE
    # 2: 2016-09-01 2016-09-01 15:00:00 1.13000 1.11990       TRUE
    # 3: 2016-09-01 2016-09-01 15:00:01 1.11911 1.11990      FALSE
    # 4: 2016-09-05 2016-09-05 15:00:00 1.11436 1.11823      FALSE
    # 5: 2016-09-05 2016-09-05 15:00:01 1.11436 1.11823      FALSE
    # 6: 2016-09-05 2016-09-05 15:00:01 1.11900 1.11823       TRUE
    # 7: 2016-09-05 2016-09-05 15:00:01 1.11436 1.11823      FALSE
    # 8: 2016-09-06 2016-09-06 15:00:00 1.12383 1.12557      FALSE
    # 9: 2016-09-06 2016-09-06 15:00:00 1.12382 1.12557      FALSE
    #10: 2016-09-06 2016-09-06 15:00:00 1.12382 1.12557      FALSE
    #11: 2016-09-06 2016-09-06 15:00:00 1.12384 1.12557      FALSE
    #12: 2016-09-06 2016-09-06 15:00:00 1.12384 1.12557      FALSE
    #13: 2016-09-06 2016-09-06 15:00:00 1.12558 1.12557       TRUE
    #14: 2016-09-06 2016-09-06 15:00:01 1.12559 1.12557      FALSE
    

    【讨论】:

    • 更好的是seq_len(.N) == which.max(price &gt; dayhigh)
    • 谢谢@MichaelChirico!更新。 seq_len 会更快,但出于我自己的好奇心,还有其他好处吗?
    • 更重要的是avoiding ifelse
    • @Mike H 非常简洁的答案适用于 dplyr df %&gt;% group_by(day) %&gt;% mutate (first_high = (seq_along(price) == which(price &gt; dayhigh)[1]))
    • 为我们其他人解码:which/which.max() 返回一个可变长度的索引向量,然后seq_len(.N) == which(...) 将其转换回一个固定长度的布尔向量。
    【解决方案3】:

    您可以使用两次ave

    #1) 确保price 大于dayhigh

    #2) 确保它在给定的子组中是第一次发生。

    ave(1:NROW(df), df$day, FUN = function(i) df$price[i] > df$dayhigh[i]) & #1
        ave(1:NROW(df), df$day, FUN = function(i) cumsum(df$price[i] > df$dayhigh[i]) == 1) #2
    #[1] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
    

    【讨论】:

      猜你喜欢
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多