首页 > 解决方案 > 从 R 中的嵌套循环中提取输出

问题描述

我正在尝试在 R 中构建嵌套的 for 循环。内部循环工作正常,但不必每次都编辑输入文件,我想将它们捆绑在一个列表中并让第二个循环按顺序处理它们。但是,我不知道如何从外循环中提取输出。目前,我可以只使用一个循环,然后将输出文件分配给另一个对象。它工作正常,但效率低下。谁能给我指点我哪里出错了,好吗?

这是一些虚构的数据。为简洁起见,这比我的真实数据小得多(七个输入文件,长度不同)。完整版有更多的标识符和值列(因此是数据类型的混合)。

# Make some data
DATA.1 <- data.frame("Type" = "Oranges", "Time" = "Day", "Group" =
 sample(rep(1:24, each = 6), replace = FALSE), "Val.1" = rnorm(144, mean = 0.5,
 sd = 1), "Val.2" = rnorm(144, mean = 100, sd = 30), "Val.3" = rnorm(144, mean = 2, 
 sd = 1))

DATA.2 <- data.frame("Type" = "Oranges", "Time" = "Day", "Group" = sample(rep(1:72, 
 each = 6), replace = FALSE), "Val.1" = rnorm(432, mean = 0.5, sd = 1) , "Val.2" = 
 rnorm(432, mean = 100, sd = 30), "Val.3" = rnorm(432, mean = 2, sd = 1) )


# Calculate means and standard deviations of data. (Will be output file during loop)
DATA.1out <- DATA.1 %>% group_by(Group) %>% summarise_at(.vars = 3:5, funs(mean, sd))
DATA.2out <- DATA.2 %>% group_by(Group) %>% summarise_at(.vars = 3:5, funs(mean, sd))

# Bind empty columns to populate with standard errors during the loop
DATA.1out <- cbind(DATA.1out, "Val.1_se" = NA, "Val.2_se" = NA, "Val.3_se" = NA)
DATA.2out <- cbind(DATA.2out, "Val.1_se" = NA, "Val.2_se" = NA, "Val.3_se" = NA)

# Loop input
DATA.in <- list(DATA.1, DATA.2)

# Loop output
DATA.out <- list(DATA.1out, DATA.2out)

# This loop calculates the cumulative standard error for each group. i.e. the mean 
# and standard deviation apply to that group only, but the standard error is 
# comprised of all the values up to and including the most recent group.

for (i in 1:2) {
  RAW.FILE <- DATA.in[[i]]
  OUTPUT.FILE <- DATA.out[[i]]
  COUNTER <- 1

  for(i in 1:nrow(OUTPUT.FILE)) {
    GROUP.NO <- data.frame(Group = c(1:COUNTER))
    TEMP <- RAW.FILE[RAW.FILE$Group %in% GROUP.NO$Group, ]
    TEMP$Val.1_se <- sd(TEMP$Val.1)/sqrt(nrow(TEMP))
    OUTPUT.FILE$Val.1_se[i] <- unique(TEMP$Val.1_se)
    TEMP$Val.2_se <- sd(TEMP$Val.2)/sqrt(nrow(TEMP))
    OUTPUT.FILE$Val.2_se[i] <- unique(TEMP$Val.2_se)
    TEMP$Val.3_se <- sd(TEMP$Val.3)/sqrt(nrow(TEMP))
    OUTPUT.FILE$Val.3_se[i] <- unique(TEMP$Val.3_se)
    COUNTER <- COUNTER + 1
  }

DATA.out[[i]] <- OUTPUT.FILE

}

可能不是最有效的方法,但至少内部循环有效。但是,我无法使输出与相关DATA.out文件匹配。目前,我最终得到一个包含许多空白数据帧的列表,并且out插槽中的相关文件等于OUTPUT.FILE. 如何将标准错误附加到现有DATA.out数据框?

标签: rfor-loop

解决方案


对 for 循环的这种轻微修改应该可以解决这个问题。在处理嵌套的 for 循环时,您应该为迭代器指定不同的变量名称,以便您可以从内部循环中引用外部循环变量。在这种情况下,通过将内部循环迭代器从 i 更改为 j,您可以将 OUTPUT.FILE 分配移动到内部循环内部以获得您想要的结果。

for (i in 1:2) {
  RAW.FILE <- DATA.in[[i]]
  OUTPUT.FILE <- DATA.out[[i]]
  COUNTER <- 1

  for(j in 1:nrow(OUTPUT.FILE)) {
    GROUP.NO <- data.frame(Group = c(1:COUNTER))
    TEMP <- RAW.FILE[RAW.FILE$Group %in% GROUP.NO$Group, ]
    TEMP$Val.1_se <- sd(TEMP$Val.1)/sqrt(nrow(TEMP))
    OUTPUT.FILE$Val.1_se[j] <- unique(TEMP$Val.1_se)
    TEMP$Val.2_se <- sd(TEMP$Val.2)/sqrt(nrow(TEMP))
    OUTPUT.FILE$Val.2_se[j] <- unique(TEMP$Val.2_se)
    TEMP$Val.3_se <- sd(TEMP$Val.3)/sqrt(nrow(TEMP))
    OUTPUT.FILE$Val.3_se[j] <- unique(TEMP$Val.3_se)
    COUNTER <- COUNTER + 1

    DATA.out[[i]] <- OUTPUT.FILE
  }


}

推荐阅读