如何使用循环在多个工作站上执行Mann-kendall测试?

时间:2019-04-02 21:31:18

标签: r loops time-series lapply

我刚刚开始使用R,并且想使用modifiedmk软件包对每月地下水位数据进行测试。我的数据框(GL)看起来像这样

GL

well    year    month   value
684     1994    Jan     8.53
684     1995    Jan     8.74
684     1996    Jan     8.88
684     1997    Jan     8.24
1001    2000    Jan     9.1
1001    2001    Jan     9.2
1001    2002    Jan     9.54
1001    2003    Jan     9.68
2003    1981    Jan     55.2
2003    1982    Jan     55.8
2003    1983    Jan     56.4
2003    1984    Jan     53.2

首先,我创建了孔的列表和用于打印结果的results_list文件

well_list <- unique(GL$well)
results_list <- vector("list", length(well_list))

然后我创建了我认为是循环的

for(i in well_list){
  results_list[[grep(i, well_list)]] <- MannKendall(GL[,4])
}
names(results_list) <- well_list

但我一直收到此错误

Error in Kendall(1:length(x), x) : length(x)<3

我可以使此代码正常工作(我从另一篇文章中获取了此代码),但我不想执行预白化方法

for(i in well_list){
tempDF <- GL1[GL$well == i, ]
c<-acf(tempDF$value,lag.max=1)
t <- dim(c$acf)
tempDF$prewhit1<-c$acf[[t[1], t[2], t[3]]]*tempDF$value
prewhitseries<-data.frame(with(tempDF,(tempDF$value[-1] - prewhit1[ 
length(prewhit1)])))
autocordata<-cbind(tempDF[-1,],prewhitseries)
results_list[[grep(i, well_list)]] <- MannKendall(autocordata[,5])}
names(results_list) <- well_list

3 个答案:

答案 0 :(得分:0)

也许使用split/lapply会更容易且更具可读性。

首先,运行测试。

sp <- split(GL, GL$well)
results_list <- lapply(sp, function(DF){
  tryCatch(MannKendall(DF[, 4]),
           error = function(e) e)
})

现在,获得没有错误的好东西。

bad <- sapply(results_list, inherits, "error")

并检查它们。

results_list[bad]
#named list()

results_list[!bad]
#$`684`
#tau = 0, 2-sided pvalue =1
#
#$`1001`
#tau = 1, 2-sided pvalue =0.089429
#
#$`2003`
#tau = 0, 2-sided pvalue =1

答案 1 :(得分:0)

类似的事情应该做。 split()沿well列拆分,为每个孔创建一个带有向量的列表。仅保留长度为3或更大的向量。然后使用MannKendall()

在其余的每个向量上运行lapply()
library(Kendall)

tt <- read.table(text="
well    year    month   value
684     1994    Jan     8.53
684     1995    Jan     8.74
684     1996    Jan     8.88
684     1997    Jan     8.24
1001    2000    Jan     9.1
1001    2001    Jan     9.2
1001    2002    Jan     9.54
1001    2003    Jan     9.68
2003    1981    Jan     55.2
2003    1982    Jan     55.8
2003    1983    Jan     56.4
2003    1984    Jan     53.2
2004    1984    Jan     53.2", header=TRUE)

tt.wells <- split(tt$value, tt$well)
tt.wells <- tt.wells[lengths(tt.wells) >= 3]

lapply(tt.wells, MannKendall)

# $`684`
# tau = 0, 2-sided pvalue =1

# $`1001`
# tau = 1, 2-sided pvalue =0.089429

# $`2003`
# tau = 0, 2-sided pvalue =1

答案 2 :(得分:0)

如果要对每口井的各个月份进行测试怎么办?

well    year    month   value
684     1994    Jan     8.53
684     1994    Feb     8.62
684     1994    Mar     8.12
684     1994    Apr     8.21
684     1995    Jan     8.53
684     1995    Feb     8.62
684     1995    Mar     8.12
684     1995    Apr     8.21
684     1996    Jan     8.53
684     1996    Feb     8.62
684     1996    Mar     8.12
684     1996    Apr     8.21
101     1994    Jan     8.53
101     1994    Feb     8.62
101     1994    Mar     8.12
101     1994    Apr     8.21
101     1995    Jan     8.53
101     1995    Feb     8.62
101     1995    Mar     8.12
101     1995    Apr     8.21
101     1996    Jan     8.53
101     1996    Feb     8.62
101     1996    Mar     8.12
101     1996    Apr     8.21

也许最终会得到一个这样的表

$pvalue 
well    Jan    Feb    Mar    Apr    May    Jun    etc
684    0.03    0.23    0.15    0.15    0.25    0.54
1001   0.21    0.54    0.25    0.01    0.02    0.02    
etc

$tau    
well    Jan    Feb    Mar    Apr    May    Jun    etc
684      0      0     1      0      1      0
1001     0      6     2      3      4      0    
etc  

对不起,我以为我会在注意的同时问我。