【问题标题】:Split a dataframe based on a column and write out the multiple split .txt files with specific names根据列拆分数据框并写出具有特定名称的多个拆分 .txt 文件
【发布时间】:2020-02-18 17:23:17
【问题描述】:

我正在处理从微观数据生成的巨大 .txt 数据帧。它的每个 .txt 输出文件大约为 3 到 4 GB!我有几百个......

对于这些怪物文件中的每一个,它都有数百个特征,有些是分类的,有些是数字的。

这是数据框的一个抽象示例:

df <- read.csv("output.txt", sep="\t", skip = 9,header=TRUE, fill = T)
df

Row  Column stimulation Compound Concentration treatmentsum Pid_treatmentsum  var1 var2  var3  ...
1    1      uns         Drug1    3             uns_Drug1_3  Jack_uns_Drug1_3  15.0 20.2  3.568 ...
1    1      uns         Drug1    3             uns_Drug1_3  Jack_uns_Drug1_3  55.0 0.20  9.068
1    1      uns         Drug2    5             uns_Drug2_5  Jack_uns_Drug2_5  100  50.2  3.568
1    1      uns         Drug2    5             uns_Drug2_5  Jack_uns_Drug2_5  75.0 60.2  13.68
1    1      3S          Drug1    3             3s_Drug3_3   Jack_3s_Drug1_3   65.0 30.8  6.58
1    1      4S          Drug1    3             4s_Drug3_3   Jack_4s_Drug1_3   35.0 69.3  2.98
.....

我想根据分类列中的共同值拆分数据框,即治疗和。 所以我可以让所有细胞一起用相同的药物和相同的剂量处理,也就是所有的“uns_Drug1_3”都放在一个 output.txt 中。

我看过类似的帖子,所以我使用了 split()

sptdf <- split(df, df$treatmentsum)

它起作用了,因为现在 sptdf 给了我数据框列表。现在我想将它们写成表格,理想情况下我想使用“Pid_treatmentsum”元素作为每个拆分文件名的名称,因为它们在拆分后应该具有完全相同的“Pid_treatmentsum”。我不太清楚该怎么做,到目前为止,我至少可以手动输入患者 ID 并通过粘贴加入他们

lapply(names(sptdf), function(x){write.table(sptdf[[x]], file = paste("Jack", x, sep = "_"))}) 

这很有效,它会写出所有具有正确标题的单个文件,但它们不是 .txt,如果我在 excel 中打开它们,我会收到警告消息它们已损坏。同时在 R 中,我收到警告消息
文件中的错误(文件,ifelse(追加,“a”,“w”)): 无法打开连接

我哪里弄错了?

考虑到显微镜下每个输出文件的绝对大小(3-4GB),这是最好的方法吗?

如果我可以进一步推动这一点,我是否可以将所有数百个大文件转储到一个文件夹中,我是否可以编写一个循环来自动执行该过程而不是一次拆分一个文件?我预见的唯一问题是显微镜输出文件总是具有相同的名称,标题为“输出”。

提前谢谢你,很抱歉发了这么长的帖子。

干杯, 机器学习

【问题讨论】:

  • 如果你想要正确的扩展名,你可以尝试paste0("Jack_", x, ".txt")lapply中命名你的文件

标签: r dataframe split


【解决方案1】:

我不认为这与 OP 的代码有很大不同,但它就是这样。

首先,一个测试数据集。我将使用内置数据集的副本iris

df <- iris
names(df)[5] <- "Pid_treatmentsum"

现在文件编写代码。

sptdf <- split(df, df$Pid_treatmentsum)
lapply(sptdf, function(DF){
  outfile <- as.character(unique(DF[["Pid_treatmentsum"]]))
  outfile <- paste0(outfile, ".txt")
  write.table(DF, 
              file = outfile,
              row.names = FALSE,
              quote = FALSE)
})

如果 Excel 抱怨文件损坏,也许 write.csv(和文件扩展名 "csv")可以解决问题。

编辑。

为了自动化上面的代码来处理许多文件,split/lapply 可以重写为一个函数。然后将调用该函数,将文件名作为参数传递。
类似于(未经测试)的东西

splitFun <- function(file, col = "Pid_treatmentsum", ...){
  X <- read.table(file, header = TRUE, ...)
  sptdf <- split(X, X[[col]])
  lapply(sptdf, function(DF){
    outfile <- as.character(unique(DF[[col]]))
    outfile <- paste0(outfile, ".txt")
    write.table(DF,
                file = outfile,
                row.names = FALSE,
                quote = FALSE)
  })
}


filenames <- list.files(pattern = "<a regular expression>")
lapply(filenames, splitFun)

【讨论】:

  • 谢谢,这很好用。抱歉,与 OP 相比,这可能没有那么有创意。我对编程太陌生了。我正在向你们所有人学习,如果我能问一个愚蠢的问题,你能解释一下 (unique(DF[["Pid_treatmentsum"]])) 部分吗?更具体地说,DF[[]} 对字符串 PiD_treatmentsum 做了什么?我是否正确,您正试图从已经拆分的数据帧中获取所有“Pid_treatmentsum”的向量/矩阵,并且 unique 将返回一个向量,因为它们在任何给定的拆分数据帧中都将具有相同的“Pid_treatmentsum”?跨度>
  • 我希望我没有失去你 :( 我可以在某处阅读更多关于此的内容吗?
  • @ML33M 我使用[[,因为它在函数内部,并且在编程时推荐使用提取器,而不是$,它应该保留用于交互模式。这个帖子Difference between [ and [[有更多的细节。
  • 谢谢你,伙计!这真是太好了!对于在同一个目录中处理数百个这些文件的厚颜无耻的问题,我是否只是简单地遍历文件夹?
  • @ML33M 查看编辑,也许它会给出如何完成的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 2017-08-15
  • 2020-01-08
  • 1970-01-01
  • 2020-09-22
  • 1970-01-01
相关资源
最近更新 更多