首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据其他变量组R使用rle()

根据其他变量组R使用rle()
EN

Stack Overflow用户
提问于 2014-05-13 14:25:56
回答 2查看 634关注 0票数 1

这确实是我几周前在这里发布的another question上的一个后续,并得到了一个答案。

在我的第一个问题中,我想找出数据集中的径流事件之间的天数。如下面的数据示例所示:

代码语言:javascript
复制
Date        Runoff   No_Days
01/01/1980  0        4
02/01/1980  0        3
03/01/1980  0        2
04/01/1980  0        1
05/01/1980  4.5      0
06/01/1980  2        0
07/01/1980  0        6
08/01/1980  0        5
09/01/1980  0        4
10/01/1980  0        3
11/01/1980  0        2
12/01/1980  0        1  
13/01/1980  1.2      0
14/01/1980  0        4      
15/01/1980  0        3
16/01/1980  0        2
17/01/1980  0        1
18/01/1980  0.8      0

我使用以下代码实现了这个目标:

代码语言:javascript
复制
DF$No_Days <-unlist(lapply(rle(DF$Runoff>0.05)$lengths,function(x) rev(seq(x:1))))
DF$No_Days <-ifelse(DF$Runoff>0.05,0,DF$No_Days)

所有这些都适用于单个数据集,即一个组的一个时间序列。然而,我现在正在挣扎的是,如何根据一个分组变量(Soil)对同一data.table中的多个时间序列数据集进行相同的操作,以完成相同的操作,例如:

代码语言:javascript
复制
Date        Runoff   No_Days  Soil
01/01/1980  0        4        Clay
02/01/1980  0        3        Clay    
03/01/1980  0        2        Clay    
04/01/1980  0        1        Clay    
05/01/1980  4.5      0        Clay
06/01/1980  2        0        Clay
07/01/1980  0        6        Clay
08/01/1980  0        5        Clay
09/01/1980  0        4        Clay
10/01/1980  0        3        Clay
11/01/1980  0        2        Clay
12/01/1980  0        1        Clay
13/01/1980  1.2      0        Clay
14/01/1980  0        4        Clay  
15/01/1980  0        3        Clay
16/01/1980  0        2        Clay
17/01/1980  0        1        Clay
18/01/1980  0.8      0        Clay
01/01/1980  0        5        Sand
02/01/1980  0        4        Sand
03/01/1980  0        3        Sand
04/01/1980  0        2        Sand
05/01/1980  0        1        Sand
06/01/1980  2        0        Sand
07/01/1980  0        11       Sand
08/01/1980  0        10       Sand
09/01/1980  0        9        Sand
10/01/1980  0        8        Sand
11/01/1980  0        7        Sand
12/01/1980  0        6        Sand
13/01/1980  0        5        Sand
14/01/1980  0        4        Sand    
15/01/1980  0        3        Sand
16/01/1980  0        2        Sand
17/01/1980  0        1        Sand
18/01/1980  0.8      0        Sand

目前,如果我运行代码,它不会区分不同的土壤类型,因此不会在每个时间序列之后‘重新启动’排序。

从阅读中可以看出,我可能需要将原始代码中的lapply()替换为by()。我认为,只要rle()首先按照土壤分组,这就会起作用,但我找不到任何方法。

所以,任何帮助,谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-13 14:35:38

如果您使用data.table包,这非常容易:

代码语言:javascript
复制
install.packages("data.table")
library(data.table)
DF = data.table(DF)

DF[,No_Days:=unlist(lapply(rle(Runoff>0.05)$lengths,function(x) rev(seq(x:1)))),by=Soil]
DF[Runoff <= 0.05, No_Days:=0]
票数 3
EN

Stack Overflow用户

发布于 2014-05-13 18:42:11

如果您也对在基R中这样做感兴趣,那么可以使用ave来获得相同的结果。为了方便起见,我会定义

代码语言:javascript
复制
countdown <- function(events) {
    unlist(with(rle(events), 
        Map(function(v,l) {
            if(v) rep.int(0,l)
            else l:1}
        , values, lengths)
    ))
}

然后,您将找到没有土壤类型的答案

代码语言:javascript
复制
DF <- transform(DF, No_Days=countdown(Runoff>0.05))

然后按土壤类型分组,您可以

代码语言:javascript
复制
DF <- transform(DF, No_Days=ave(Runoff>0.05, Soil, FUN=countdown))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23634018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档