在站点循环中嵌套时间序列循环的成对差异 - 多次

问题描述 投票:0回答:1

我有一个数据框,其中行是年(~30 年)和站点(~300 个站点),列是物种丰度(~200 spp)。

数据看起来像:

网站 特殊 1 特殊 2 物种 n
站点 1 1年级 0.4 0.0 0.0
站点 1 第二年 0.8 0.5 1.0
站点 1 3年级 0.0 0.7 1.3
站点 1 四年级 0.0 0.4 1.6
站点 2 1年级 1.2 0.1 0.4
站点 2 第二年 1.0 0.0 0.5
站点 2 3年级 1.0 0.0 0.4
站点 3 1年级 2.0 0.0 1.0
站点 3 第二年 1.0 0.0 0.8
站点 3 3年级 0.5 0.0 1.0
站点 3 四年级 0.0 0.0 0.3

*注意数据集的年份调查不一致。

我需要的是在站点循环内构建时间序列(年)的嵌套循环。然后,通过两种不同的场景运行时间成对比较(例如,在 R 中使用 betapart 或素食包):1)锚定每个站点的第一年(第 1 年)并比较随后的年份(即 yr1 与 yr2;yr1 与 yr3) ; yr1 vs yr4 ...),以及 2)比较连续年份之间的差异(即 yr1 vs yr2;yr2 vs yr3;yr3 vs yr4 ...)。

我没有任何最终代码,但我认为我需要运行这样的东西(我确信比这复杂得多):

# prior need to define empty matrix to beta outputs
beta.matrix <- data.frame(curp = df$Site, Year = df$Year, beta.bray.bal=NA, beta.bray.gra=NA, beta.bray=NA)

# nested loop pairwise dissimilarities
for(i in 1:unique(df$Site)){ # outer loop are sites
  
  for(j in 1:(nrow(df$Year))){ # the inner loop are years and will run one time for each iteration of the outer loop.
    
   beta.x <- beta.pair.abund(x, index.family="bray") # this is the pairwise function in betapart package in R
    
    #the function *beta.pair.abund* returns three outputs that I expect to store in the empty matrix I defined previusly: https://cran.r-project.org/web/packages/betapart/betapart.pdf

    beta.matrix$beta.bray.bal[i]<-as.matrix(beta.x[[1]])[unique(df$Site)+i, i] 
    beta.matrix$beta.bray.gra[i]<-as.matrix(beta.x[[2]])[unique(df$Site)+i, i]
    beta.matrix$beta.bray[i]<-as.matrix(beta.x[[3]])[unique(df$Site)+i, i]
    
  }

 }

任何关于如何做的想法将不胜感激。

r loops time-series nested-loops pairwise
1个回答
0
投票

此解决方案基于您提供的样本数据。需要对代码进行一些修改才能在您的完整数据集上运行:

library(betapart)

df <- data.frame(Site = paste(rep("Site", 11), c(1,1,1,1,2,2,2,3,3,3,3)),
                 Year = paste(rep("Year", 11), c(1,2,3,4,1,2,3,1,2,3,4)),
                 `Specie 1` = c(0.4, 0.8, 0.0, 0.0, 1.2, 1.0, 1.0, 2.0, 1.0, 0.5, 0.0),
                 `Specie 2` = c(0.0, 0.5, 0.7, 0.4, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
                 `Specie 3` = c(0.0, 1.0, 1.3, 1.6, 0.4, 0.5, 0.4, 1.0, 0.8, 1.0, 0.3),
                 check.names=FALSE)

# Define empty matrix for beta outputs (note this differs from 
# your example as it has three added columns to accommodate
# both "subsequent" and "successive" outputs)
beta.matrix <- data.frame(curp = df$Site, 
                          Year = df$Year, 
                          subs.beta.bray.bal=NA, 
                          subs.beta.bray.gra=NA, 
                          subs.beta.bray=NA,
                          succ.beta.bray.bal=NA, 
                          succ.beta.bray.gra=NA, 
                          succ.beta.bray=NA)

# Create loop vector for every Site
for(i in unique(df$Site)) {
  
  # Get row index for first value of each group e.g. "Year 1"
  x <- min(which(df$Site == i)) 
  # Counter, only needed for calculating "successive years"
  y <- 0
  
  # Create loop vector one less than site observations 
  # e.g. exclude "Year 1"
  for(j in 1:(length(which(df$Site == i))-1)) {
    
    # Calculate beta.pair.abund for x and x+j (subsequent years)
    # ATTENTION: edit column index "3:5" to match your actual data
    # e.g. df[c(x,x+j),3:200]
    beta.subs <- beta.pair.abund(df[c(x,x+j),3:5], index.family="bray")
    # Add result to beta.matrix (leave the column index as is)
    beta.matrix[x+j,3:5] <- do.call(cbind, beta.subs)
    
    # Calculate beta.pair.abund for x+y and x+j (successive years)
    # ATTENTION: edit column index "3:5" to match your actual data
    # e.g. df[c(x+y, x+j),3:200]
    beta.succ <- beta.pair.abund(df[c(x+y, x+j),3:5], index.family="bray")
    # Add result to beta.matrix
    beta.matrix[x+j,6:8] <- do.call(cbind, beta.succ)
    # Increase "counter" by 1 for each inner loop iteration
    y <- y + 1

  }
  
}

beta.matrix
#      curp   Year subs.beta.bray.bal subs.beta.bray.gra subs.beta.bray   succ.beta.bray.bal succ.beta.bray.gra succ.beta.bray
# 1  Site 1 Year 1                 NA                 NA             NA                   NA                 NA             NA
# 2  Site 1 Year 2         0.00000000         0.70370370     0.70370370           0.00000000         0.70370370     0.70370370
# 3  Site 1 Year 3         1.00000000         0.00000000     1.00000000           0.25000000         0.05232558     0.30232558
# 4  Site 1 Year 4         1.00000000         0.00000000     1.00000000           0.15000000         0.00000000     0.15000000
# 5  Site 2 Year 1                 NA                 NA             NA                   NA                 NA             NA
# 6  Site 2 Year 2         0.06666667         0.05833333     0.12500000           0.06666667         0.05833333     0.12500000
# 7  Site 2 Year 3         0.00000000         0.09677419     0.09677419           0.00000000         0.03448276     0.03448276
# 8  Site 3 Year 1                 NA                 NA             NA                   NA                 NA             NA
# 9  Site 3 Year 2         0.00000000         0.25000000     0.25000000           0.00000000         0.25000000     0.25000000
# 10 Site 3 Year 3         0.00000000         0.33333333     0.33333333           0.13333333         0.07878788     0.21212121
# 11 Site 3 Year 4         0.00000000         0.81818182     0.81818182           0.00000000         0.66666667     0.66666667

请注意,这将为每个组返回“第一年”的 NA。这是预期的行为。

还有一点,在 R 中有比循环更好的方法。尽管您的数据只有约 9,000 行并且此循环应该不到一分钟,但 R 可以更好地处理矢量化方法。查看 tidyverse 使用诸如

dplyr
tidyr
.

等包的更快、非循环的替代方案
© www.soinside.com 2019 - 2024. All rights reserved.