【问题标题】:For loop returns last resultFor 循环返回最后一个结果
【发布时间】:2018-06-05 10:01:34
【问题描述】:

我有少量 csv 文件,每个文件包含两列数值。我想编写一个 for 循环来读取文件,对列求和,并将每个 csv 的总和存储在一个数字向量中。这是我最近的一次:

allfiles <- list.files()
for (i in seq(allfiles)) {
     total <- numeric()
     total[i] <- sum(subset(read.csv(allfiles[i]), select=Gift.1), subset(read.csv(allfiles[i]), select=Gift.2))
     total
}

我的结果是所有 NA 保存最后一个文件的值。我知道每次执行 for 循环时我都会覆盖每次迭代,我认为*我需要对索引做一些事情。

【问题讨论】:

  • DnstnRmsy,如果任何一个答案满足您的需求,SO 习惯上通过选择它左侧的复选标记来“接受”答案。它不仅向帮助过的人提供了一些“感谢”和赞誉(可能是通过投票),而且对于您之后出现的任何类似问题,它还有效地将问题标记为“已解决/已解决”。
  • 10-4,r2Evans。再次感谢您的帮助!
  • r2Evans,我只能“接受”一个答案吗?
  • 您只能“接受”一个,即使多个答案满足您的需求,StackExchange 就是这样工作的。您可以“点赞”零个或多个,这意味着如果您喜欢所有内容,那么您可以点赞所有内容。

标签: r for-loop


【解决方案1】:

第一个问题是您没有预先分配(或正确附加到)total 的正确长度。无论如何,我建议不要使用这种方法。

有几种方法可以做到这一点,但 R-onic(我的术语,基于 pythonic ......我知道,它不能很好地流动)基于向量/列表。

alldata <- sapply(allfiles, read.csv, simplify = FALSE)
totals <- sapply(alldata, function(a) sum(subset(a, select=Gift.1), subset(a, select=Gift.2)))

我经常喜欢这样,将“原始/未更改”数据保存在一个列表中,然后反复从中提取。例如,如果文件很大并且读取它们的时间很长,那么如果您意识到您还需要 Gift.3 并按照您的方式进行操作,那么您需要重新读取整个数据集。但是,使用我的方法,您只需更新第二个 sapply 以包含更改并在已加载的数据上重新运行。 (我的大部分理由是基于不受信任的数据、通常未使用的部分或其他可能不适合您的因素。)

如果您真的想将代码减少到一行,例如:

totals <- sapply(allfiles, function(fn) {
  x <- read.csv(fn)
  sum(subset(x, select=Gift.1), subset(x, select=Gift.2))
})

【讨论】:

  • 感谢深思熟虑的回复,r2evans。并再次感谢您的实用建议;完全有道理。根据我个人的理解,设置长度对 for 循环有什么作用?正如上面 Onyambu 所建议的,我设置了长度,而不是最后一个文件的 NA 和值,我得到了“0.000”和最后一个文件的值。
【解决方案2】:
allfiles <- list.files()
total <- numeric()
for (i in seq(allfiles)) {
 total[i] <- sum(subset(read.csv(allfiles[i]), select=Gift.1), subset(read.csv(allfiles[i]), select=Gift.2))
}
 total

如果可能的话,试着在手头之前给总数一个已知的长度,即total&lt;-numeric(length(allfiles))

【讨论】:

  • 感谢您的快速回复,Onyambu。这可能是基本的,但是设置对象的长度与 for 循环有什么关系呢? (我按照你的建议设置了长度,我的结果都是“0.000”,除了最后一个文件,它给了我一个值。)
  • 如果这回答了您的问题,您可以继续并接受它以关闭问题。你也可以投票。谢谢
  • DnstnRmsy,有两件事:(1)你正在 覆盖 total 每次都通过你的循环,所以你丢失了所有以前的信息,所以至少 total &lt;- numeric()应该在for 循环之外; (2) 尽管您可以动态地增长向量/列表,但每次附加到向量时它都会复制数据。 (从长远来看,这会变得很昂贵。)为了抢占先机,如果您知道它将获得多大(或至少是一个上限),那么请预先分配空间,因为不会发生向量的单个元素的替换复制成本。
  • 感谢@r2evans 回答了您提出的问题
猜你喜欢
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 2023-04-09
  • 2021-08-14
  • 1970-01-01
  • 2016-06-27
相关资源
最近更新 更多