【问题标题】:Count the number of elements between 2 dates conditionally on a variable in R有条件地计算 R 中变量的两个日期之间的元素数
【发布时间】:2017-01-19 02:49:34
【问题描述】:

我正在尝试计算两个日期之间低于某个阈值(比如说小于或等于 50)的降水量。

基本上,我有一个向量cuts,其中包含我想要计算的日期。我想使用cuts 向量将数据集“子集”到不同的 bin 中,然后计算下雨少于 50 毫米的事件的数量。

我目前正在使用 dplyr 和 for 循环,但没有任何效果。

set.seed(12345)
df = data.frame(date = seq(as.Date("2000/03/01"), as.Date("2002/03/01"), "days"), 
                precipitation = rnorm(length(seq(as.Date("2000/03/01"), as.Date("2002/03/01"), "days")),80,20))
cuts = c("2001-11-25","2002-01-01","2002-02-18","2002-03-01")
for (i in 1:length(cuts)) {
  df %>% summarise(count.prec = if (date > cuts[i] | date < cuts[i+1]) {count(precipitation <= 50)})
}

但是我有这个错误信息:

Error: no applicable method for 'group_by_' applied to an object of class "logical"
In addition: Warning message:
In if (c(11017, 11018, 11019, 11020, 11021, 11022, 11023, 11024,  :
  the condition has length > 1 and only the first element will be used

这也不起作用:

for (i in 1:length(cuts)) {
  df %>% if (date > cuts[i] | date < cuts[i+1])%>% summarise(count.prec = count(precipitation <= 50))
}

【问题讨论】:

    标签: r date dplyr


    【解决方案1】:

    你可以试试:

    df %>%
      group_by(gr = cut(date, breaks = as.Date(cuts))) %>%
      summarise(res = sum(precipitation <= 50))
    

    这给出了:

    # A tibble: 4 × 2
              gr   res
          <fctr> <int>
    1 2001-11-25     1
    2 2002-01-01     4
    3 2002-02-18     2
    4         NA    40
    

    或者按照@Frank 所述-您可以将summarise() 替换为tally(precipitation &lt;= 50)

    【讨论】:

    • 好的,我明白了。它计算sum 函数中TRUEFALSE 的数量。当它不匹配时,它会报告 NA?
    • @M.Beausoleil 没错。在cuts 中指定的范围之外,您有 40 个日期具有precipitation &lt;= 50。如果您想从结果中删除它,您可以简单地将 ... %&gt;% na.omit()... %&gt;% filter(!is.na(gr)) 添加到链中。
    • 只需在末尾添加%&gt;% filter(!is.na(gr))即可删除NA行!谢谢!非常聪明。
    • summarise 而不是你的tally(precipitation &lt;= 50) 似乎可以工作。
    • @M.Beausoleil 你需要tally(precipitation &lt;= 50),不需要sum()。此外,您不能在tally() 中使用res = ...
    【解决方案2】:

    我们可以尝试使用 data.table 进行非 equi 连接

    library(data.table)#v1.9.7+
    df2 <- data.table(cuts1 = as.Date(cuts[-length(cuts)]), cuts2 = as.Date(cuts[-1]))
    setDT(df)[df2, .(Count = sum(precipitation <=50)),
               on = .(date > cuts1,  date < cuts2), by = .EACHI]
    #         date       date Count
    #1: 2001-11-25 2002-01-01     1
    #2: 2002-01-01 2002-02-18     4
    #3: 2002-02-18 2002-03-01     2
    

    【讨论】:

    • 我有这个错误:Error in [.data.table(setDT(df), df2, .(Count = sum(precipitation &lt;= : could not find function "."
    • @M.Beausoleil 最近在data.table的devel版本中引入了。
    • 是的,我的版本是‘1.9.6’
    • @M.Beausoleil 如果您下载开发版,它应该可以工作
    猜你喜欢
    • 2021-10-19
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 2018-11-29
    • 1970-01-01
    相关资源
    最近更新 更多