【问题标题】:Save single data frames found within a list by applying a for loop通过应用 for 循环保存在列表中找到的单个数据帧
【发布时间】:2019-08-05 23:34:11
【问题描述】:

我必须处理多个数据帧才能执行同一组操作。因此,我将它们插入到一个列表中,并通过使用 lapply 执行某种操作。 然后,我想通过使用 for 循环将每个数据帧分别保存为 .txt 文件。这是我写的代码:

all <- lapply(names(sampleList),function(mysample){
  aux <- read.table(sampleList[[mysample]], col.names=c("Chromosome","Position","Ref_allele","Alt_allele","Fraction","Fw_ref","Rv_ref","Fw_alt","Rv_alt"))
  aux <- mutate(aux, ID=paste0(Chromosome, ":", Position)) %>% distinct(ID, .keep_all=T)
})

for( i in 1:length(all))
  write.table(all[i], paste0(all[i],"_filtered.txt"))

我希望有 n 个新数据帧,命名为原始数据帧 + _filtered 最后。但这就是实际发生的情况:

Error in file(file, ifelse(append, "a", "w")) : 
  cannot open the connection
In addition: Warning message:
In file(file, ifelse(append, "a", "w")) :
  cannot open file 'list(Chromosome = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 [... truncated]

但这不是我的数据框包含的内容。通过 View(as.data.frame(all[n])) 我看到我的数据框看起来很正常。

非常感谢您的帮助。

【问题讨论】:

  • write.table 的第二个参数应该是文件名,而是 paste0(all[i],...),它是 data.frame(嵌入长度为 1 的 list),而不是文件名.也许你可以用Map(write.table, all, paste0(names(all), "_filtered.txt")) 完全替换你的for 循环。
  • (这样写让我很痛苦......我建议您不要将变量命名为与基本 R 函数相同:allany 很常见,以至于它其他人可能有点难以阅读您的代码,更难解决问题(尤其是如果您不理解错误 object of type 'closure' is not subsettable)。)

标签: r


【解决方案1】:

这里可以做几件事:

for( i in 1:length(all))
  write.table(all[i], paste0(all[i],"_filtered.txt"))

首先,第二个参数应该是一个字符串,但是您的 paste0(all[i],...) 正在处理框架本身(all[i] 是嵌入在长度为 1 的 list 中的 data.frame),而不是它。你可能会逃脱:

for( i in 1:length(all))
  write.table(all[i], paste0(names(all)[i], "_filtered.txt"))

但是您可以通过扩展您的词典从 lapply (它在 一个向量/数据列表上执行一个函数)来继续“在帧列表上操作”的主题(这很棒,顺便说一句) ) 包括Mapmapply,它们将一个或多个向量/列表压缩到一个函数的各个参数中。前期:

Map(write.table, all, paste0(names(all), "_filtered.txt"))

应按您的意愿保存所有内容(并返回来自write.table 的返回值列表,这可能没有用)。

说明:Map(myfun, 1:3, c('a','b','c'), c('X','Y','Z')) 在内部展开为

myfun(1, 'a', 'X')
myfun(2, 'b', 'Y')
myfun(3, 'c', 'Z')

所以这两个几乎是等价的:

lapply(1:3, myfun)
Map(myfun, 1:3)

(它们之间存在一些非常小的性能差异。如果您知道自己始终只有一个向量,请使用lapply。)

因此,为了延续“尽可能多地矢量化”的主题(这是 R-circles 中的常见口头禅),我们在早期使用 paste0(names(all), "_filtered.txt") 生成文件名,然后将两个列表/矢量对象传递给 @987654338 @:数据列表和文件名。

【讨论】:

  • 艾伦,如果答案解决了您的问题,请accept it;这样做不仅为回答者提供了一些积分,而且还为有类似问题的读者提供了一些关闭。尽管您只能接受一个答案,但您可以选择对您认为有帮助的人进行投票。 (如果仍有问题,您可能需要编辑您的问题并提供更多详细信息。)
猜你喜欢
  • 2020-04-25
  • 2022-01-20
  • 2022-06-29
  • 2021-01-03
  • 1970-01-01
  • 2022-11-26
  • 1970-01-01
  • 2020-05-28
  • 2019-10-09
相关资源
最近更新 更多