【问题标题】:Skip iteration and return NA in nested for loop in R跳过迭代并在 R 中的嵌套 for 循环中返回 NA
【发布时间】:2021-03-13 07:02:46
【问题描述】:

给定数据框:

test <- structure(list(IDcount = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), year = c(1, 
2, 3, 4, 5, 1, 2, 3, 4, 5), Otminus1 = c(-0.28, -0.28, -0.44, 
-0.27, 0.23, -0.03, -0.06, -0.04, 0, 0.02), N.1 = c(NA, -0.1, 
0.01, 0.1, -0.04, -0.04, -0.04, -0.04, -0.05, -0.05), N.2 = c(NA, 
NA, -0.09, 0.11, 0.06, NA, -0.08, -0.08, -0.09, -0.09), N.3 = c(NA, 
NA, NA, 0.01, 0.07, NA, NA, -0.12, -0.13, -0.13), N.4 = c(NA, 
NA, NA, NA, -0.04, NA, NA, NA, -0.05, -0.05), N.5 = c(NA, NA, 
NA, NA, NA, NA, NA, NA, NA, -0.13)), row.names = c(NA, -10L), groups = structure(list(
    IDcount = c(1, 2), .rows = structure(list(1:5, 6:10), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = 1:2, class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

和一个结果数据框:

results <- structure(list(IDcount = c(1, 2), N.1 = c(NA, NA), N.2 = c(NA, 
NA), N.3 = c(NA, NA), N.4 = c(NA, NA), N.5 = c(NA, NA)), row.names = c(NA, 
-2L), class = "data.frame")

我想执行一个嵌套的 for 循环,如下所示:

index <- colnames(test) %>% str_which("N.")

betas <- matrix(nrow=length(unique(test$IDcount)), ncol=2)
colnames(betas) <- c("Intercept", "beta")

for (j in colnames(test)[index]) {
  
  for (i in 1:2) {
    
    betas[i,] <- coef(lm(Otminus1~., test[test$IDcount==i, c("Otminus1", j)]))
  }
  
  betas <- data.frame(betas)
  
  results[[j]] <- betas$beta
}

for 循环应该在每一列和每个 ID 上运行回归,并将系数写入数据框“结果”。 只要每个 ID 在每一列中都有一个值,这就行得通。不幸的是,我的数据框“test”在“N.5”列中缺少值。因此无法执行回归和循环,因为此 ID 的所有值都是 NA。

我现在想调整我的循环,以便仅当特定列中的某个 ID 至少有一个非 NA 值时才执行迭代。

按照这个解释R for loop skip to next iteration ifelse,我尝试实现以下内容:

for (j in colnames(test)[index]) {
  
  for (i in 1:2) {
    
    if(sum(is.na(test[which(test[,1]==i),.]))==length(unique(test$year))) next
    
    betas[i,] <- coef(lm(Otminus1~., test[test$IDcount==i, c("Otminus1", j)]))
  }
  
  betas <- data.frame(betas)
  
  results[[j]] <- betas$beta
}

但这不起作用。

我希望收到如下所示的数据框“结果”:

IDcount  N.1    N.2   N.3   N.4    N.5
 1       0.1    0.2   0.5    0.3   NA
 2      -5,3   -0.8  -0.4   -0.1  -0.1

任何帮助将不胜感激!

【问题讨论】:

    标签: r loops nested iteration skip


    【解决方案1】:

    您可以使用colSums 进行检查:

    index <- colnames(test) %>% str_which("N.")
    
    betas <- matrix(nrow=length(unique(test$IDcount)), ncol=2)
    colnames(betas) <- c("Intercept", "beta")
    
    for (j in colnames(test)[index]) {
      
      for (i in 1:2) {
        tmp <- test[test$IDcount==i, c("Otminus1", j)]
        if(any(colSums(!is.na(tmp)) == 0)) next
        betas[i,] <- coef(lm(Otminus1~., tmp))
      }
      betas <- data.frame(betas)
      results[[j]] <- betas$beta
    }
    

    【讨论】:

    • 感谢您的帮助!代码中的循环通过了,但在到达“N.4”和“N.5”列时似乎停止将回归系数写入数据框“结果”。我已经编辑了我的问题,所以你可以看到我想要达到的结果;)
    • 实际上betas$beta 对于N.4N.5 都不是NA。见coef(lm(Otminus1~., test[test$IDcount==1, c("Otminus1", 'N.5')]))coef(lm(Otminus1~., test[test$IDcount==1, c("Otminus1", 'N.4')]))
    • 你是对的!再次感谢您的帮助;)
    • 是否有一种简单的方法可以切换 x 和 y 变量,并且在回归中不整合任何截距,以便它声明 lm(.~Otminus1 -1, tmp)
    • 不确定那里发生了什么。也许您可以将其作为一个新问题提出?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2019-05-17
    相关资源
    最近更新 更多