【问题标题】:write.table inside a function applied to a list of data frames overwrite outputs应用于数据帧列表的函数中的 write.table 覆盖输出
【发布时间】:2020-04-10 01:39:38
【问题描述】:

我几乎完成了messy code 以将几种统计方法/测试应用于来自不同流域的 11 个数据帧,其中物理化学参数作为变量。我达到了目标,但我需要做到这一点。 因此,首先我创建了一个计算相关性的函数,并将结果保存为 .txt 表格和 .pdf 图像。 一次将函数运行到一个数据帧时效果很好(为此,您应该使用read.table 单独导入每个数据帧,下面的代码中没有写)。 因为我希望它能够正常工作,所以列出了 11 个数据帧并使用lapply 对每个数据帧运行该函数。它的工作原理是给我一个列表 (corr),其中包含每个数据帧的相关结果。

问题来了:

  1. 列表cor 与每个数据帧的相关结果看起来像是有值而不是数据帧,所以我不知道如何访问或保存它们(请参阅环境/数据窗口中的corr 列表)。好吧,直到这里,至少看起来相关结果在某处存在。
  2. 第二个问题是,当我运行corr<-lapply(PQ_data, cor_PQ) 时,它有一行使用计算的原始数据帧的部分名称(例如PQ_data"AgIX_E_PQ" 所以cor_PQ(PQ_data[["AgIX_E_PQ"]] 的表和图应该分别得到名称“mCorAgIX_E_PQ.txt”和“CorAgIX_E_PQ.pdf”),我只得到一个输出(mCorX[[I]].txt 和 CorX[ [i]].pdf) 与最后一个数据帧相关结果。也就是说,每个数据帧相关结果的表格和图像都被覆盖到这个泛型 mCorX[[I]].txt、CorX[[i]].pdf 文件中。

现在我想必须定义“i”或其他东西来避免这种情况。我应该为PQ_data 定义cor_PQ 函数而不是X

如果有人能看到我失败的地方,我将不胜感激任何帮助解决这个问题。

我的数据:PQ_data /将其保存在您的工作区中并用它修复setwd。 我的代码:

rm(list=ls(all=TRUE))
cat("\014")

setwd("C:/Users/Sol/Documents/ProyectoTítulo/CalidadAgua/Matrices/Regs") #my workspace

PQ_files<-list.files(path="C:/Users/Sol/Documents/ProyectoTítulo/CalidadAgua/Matrices/Regs",
                     pattern="\\_PQ.txt") #my list of 14 dataframes in my workspace.
PQ_data<-lapply(PQ_files, read.table) #read tables of the 14 dataframes in the list.
names(PQ_data)<-gsub("\\_PQ.txt","", PQ_files) #name the 14 dataframes with their original names.

#FUNCTION TO COMPUTE CORRELATIONS, SAVE TABLES AND PLOTS.
cor_PQ<-function(X) {
  corPQ<-cor(X, use="pairwise.complete.obs")
  outputname.txt<-paste0("mCor",deparse(substitute(X)),".txt")
  write.table(corPQ, file=outputname.txt)
  outputname.pdf<-paste0("Cor",deparse(substitute(X)),".pdf")
  pdf(outputname.pdf)
  plot(X)
  dev.off()
  return(corPQ)
}

corr<-lapply(PQ_data, cor_PQ)

之后,正如我所说,得到一个名为“corr”的列表,其中包含 11 个元素,其中包含来自列表 (PQ_data) 中每个数据帧的相关结果,但是当我将“corr”列表固定在我的环境/数据窗口(它们不显示蓝色 R 箭头来展开元素)。 ` 我只得到 2 个名为 mCorX[[I]].txt 和 CorX[[i]].pdf 的输出文件,仅显示最后一个数据帧相关结果,因为 write.table 和 .pdf 函数会覆盖前 10 次计算的结果。 再次,我将不胜感激任何帮助。我真的需要推动才能抓住这个想法。 谢谢!!!

【问题讨论】:

  • 你可以 lapply(names(PQ_data), cor_PQ) 然后将 X 替换为 PQ_data[[X]] 并将 deparse(substitute(X)) 替换为 X 在函数 cor_PQ 中。 2个附加说明:(1)我会在函数cor_PQ中使用除cor_PQ之外的变量名和(2)你的意思是绘制X(即数据框)还是相关矩阵?
  • 您好,感谢您的支持。当我将PQ_data[[X]] 放在我的cor_PQ 函数中时,由于括号而出现意外错误。我应该在哪里更换它?关于你的笔记,(1)你的意思是cor_PQ&lt;-cor(X, use="pairwise.complete.obs")中的cor_PQ应该被定义为另一个变量吗?我想我不知道为什么会这样,并且(2)对于plot(x),我希望函数绘制来自计算的数据框(总共14个)的相关结果,以便能够按照通用方法将其保存为@ 987654354@
  • See here 提出一个可重复的问题——其中包括要处理的数据样本。现在我们无法运行您的代码,也看不到任何输出。还请重读minimal reproducible exampleminimal 部分——将问题简化为最重要的部分,这样人们可以更轻松地帮助解决问题,并且是您自己调试的良好第一步
  • @camille 我刚刚编辑了我的帖子并添加了我的数据,以便您检查和运行。感谢您的时间和支持。

标签: r pdf lapply overwrite write.table


【解决方案1】:

lapply 不会将列表名称发送给函数。因此,尽管该功能适用​​于单个文件,但不适用于文件列表。此外,由于文件没有名称,所有生成的文件都被赋予相同的名称,因此所有新文件都会覆盖以前存在的文件,最后你得到的输出只有 1 个文件,这是列表中的最后一个元素。您可以使用下面的函数,我们将名称作为不同的参数发送,以将名称分配给文件。

cor_PQ<-function(X, Y) {
   corPQ<-cor(X, use="pairwise.complete.obs")
   outputname.txt<-paste0("mCor",Y,".txt")
   write.table(corPQ, file= outputname.txt)
   outputname.pdf<-paste0("Cor",Y,".pdf")
   pdf(outputname.pdf)
   plot(X)
   dev.off()
   return(corPQ)
}

现在使用Map 应用相同的功能。

Map(cor_PQ, PQ_data, names(PQ_data))

我们也可以使用purrr中的imap来应用这个功能。

purrr::imap(PQ_data, cor_PQ)

【讨论】:

  • 哇!这正是我想要的。惊人的!那么,这意味着当我们在数据帧列表上应用函数时,我们必须将第二个变量(“Y”)视为列表中的每个数据帧?再次感谢罗纳克
  • @CristóbalJarabaNilo 仅当您想在函数中的某处使用名称时才需要考虑第二个变量。
  • 我不太确定为什么会这样。我的意思是,这也导致旧的lapply(PQ_data, cor_PQ) 被赋予一个包含所有相关结果的列表,而不是从不同的数据帧中产生单独的结果?或者这样做需要定义第二个变量?如果我不使用名称,只使用索引,并且想要生成单独的输出,我应该定义第二个变量[i]?再次感谢您的支持,作为一个特别的问题,您能否推荐我一些阅读/观看/练习并学习所有关于 R 的东西?我决定了解更多。谢谢
  • 好吧,为了简化一点,看到 names(PQ_data) 返回它的名称,但 PQ_data[[1]] 没有在 names(PQ_data) 中看到的名称,因此你得到的文件名称为 mCorX[[I]].txt
猜你喜欢
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多