首页 > 解决方案 > 按组运行 R 代码

问题描述

我有以下代码来查找最大和温度都>相应的第 90 个百分位数的日子。当我有一个站 ( df) 的数据框时,代码可以正常工作。

#data for one station
df
  Date     tmax  tmin  max90p min90p
 1962-7-2  31   21     29     19
 1962-7-3  32   23     29     19
  ...      ...  ...    ...    ...

library(data.table)
setDT(df)
d= df[, hotday := +(tmax>= max90p & tmin>=min90p)
][, EventLength := with(rle(hotday), rep(lengths,lengths))
][hotday == 0, EventLength := 0]

但我需要为 133 个站点运行此代码,因此我将所有站点合并到一个数据帧 ( dfall) 中。我曾尝试使用group_by()indplyr来运行代码,但没有奏效。

#All stations in one df
dfall
St_ID  Date     tmax  tmin  max90p min90p
4257   1962-7-2  31   21     29     19
...     ...      ...  ...    ...    ...
4263   1962-7-2  34   25     32     24
...     ...      ...  ...    ...    ...

d= dfall%>%
  group_by(St_ID)%>%
  dfall[, hotday := +(tmax>= max90p & tmin>=min90p)
  ][, EventLength := with(rle(hotday), rep(lengths,lengths))
  ][hotday == 0, EventLength := 0]


Error in `[.tbl_df`(., df00[, `:=`(hotday, +(tmax >= max90p & tmin >=  : 
  object 'hotday' not found

任何想法,谢谢你的帮助

标签: rdplyrgroup-by

解决方案


一、rleid()andfifelse()函数可以用来精简OP的代码

library(data.table)
setDT(df)[, hotday := +(tmax >= max90p & tmin >= min90p)][
  , EventLength := fifelse(hotday > 0, .N, 0), by = rleid(hotday)][]
         Date tmax tmin max90p min90p hotday EventLength
1: 1962-07-02   31   21     29     19      1           2
2: 1962-07-03   32   23     29     19      1           2
3: 1962-07-04   28   17     29     19      0           0
4: 1962-07-05   27   18     29     19      0           0
5: 1962-07-06   31   21     29     19      1           3
6: 1962-07-07   32   23     29     19      1           3
7: 1962-07-08   32   23     29     19      1           3

(有关可重复的数据,请参阅下面的数据部分)

现在,St_ID可以包含在分组中了。

library(data.table)
setDT(dfs)[, hotday := +(tmax >= max90p & tmin >= min90p)][
  , EventLength := fifelse(hotday > 0, .N, 0), by = .(St_ID, rleid(hotday))][]
   St_ID       Date tmax tmin max90p min90p hotday EventLength
1:  4257 1962-07-02   31   21     29     19      1           2
2:  4257 1962-07-03   32   23     29     19      1           2
3:  4257 1962-07-04   28   17     29     19      0           0
4:  4257 1962-07-05   27   18     29     19      0           0
5:  4257 1962-07-06   31   21     29     19      1           1
6:  6342 1962-07-02   32   23     29     19      1           2
7:  6342 1962-07-03   32   23     29     19      1           2

数据

单个站的可重现数据:

library(data.table)
df <- fread(
"Date      tmax tmin   max90p min90p
 1962-7-2  31   21     29     19
 1962-7-3  32   23     29     19
 1962-7-4  28   17     29     19
 1962-7-5  27   18     29     19
 1962-7-6  31   21     29     19
 1962-7-7  32   23     29     19
 1962-7-8  32   23     29     19
")

多个站点的可重现数据(包括列St_ID):

dfs <- fread(
"St_ID Date      tmax tmin   max90p min90p
 4257  1962-7-2  31   21     29     19
 4257  1962-7-3  32   23     29     19
 4257  1962-7-4  28   17     29     19
 4257  1962-7-5  27   18     29     19
 4257  1962-7-6  31   21     29     19
 6342  1962-7-2  32   23     29     19
 6342  1962-7-3  32   23     29     19
")

推荐阅读