r - 将一个 csv 文件拆分为多个 txt 文件

Posted

技术标签:

【中文标题】r - 将一个 csv 文件拆分为多个 txt 文件【英文标题】:r - split one csv file into multiple txt files 【发布时间】:2017-09-18 20:05:25 【问题描述】:

我需要将一个包含大约 9 列和 9,000 多行的大型 .csv 文件拆分为每行单独的 .txt 文件,并以第一列中的名称命名每个新生成的文件。

例如 对于 .csv 文件:

01001_r1    32.4327 -86.6190    0.65    0.20    0.15    1.33    5.47    8
01001_r2    32.4327 -86.6190    0.65    0.20    0.15    1.33    5.46    8
01001_r3    32.4327 -86.6190    0.80    0.15    0.05    1.33    5.23    10
01003_r1    30.4887 -87.6918    0.65    0.20    0.15    1.33    5.23    9
01003_r2    30.4887 -87.6918    0.80    0.15    0.05    1.33    5.25    9
01003_r3    30.4887 -87.6918    0.65    0.20    0.15    1.33    4.96    8

我最终会得到 6 个文件,每个文件一行。

输出文件中的列需要“制表符分隔”,并且文件不得包含行名或列名。

例如,输出文件应如下所示:

01001_r1    32.4327 -86.6190    0.65    0.20    0.15    1.33    5.47    8

这就是我走到这一步的地方:

#set 'working directory'
setwd('C:/Users/Data/soils_data/sitesoil_in')

#identify data frame from .csv file
sd <- read.csv('site_soil.csv', sep="\t", header=F, fill=F)

lapply(1:nrow(sd), function(i) write.csv(sd[i,],
                                         file = paste0(sd[i,1], ".txt"),
                                         row.names = F, header = F,
                                         quote = F))

这是我为每个输出文件得到的:

文件名:01001_r1

V1,V2,V3,V4,V5,V6,V7,V8,V9
01001_r1,32.4327,-86.619,0.65,0.2,0.15,1.33,5.47,8

我无法消除列名或用制表符分隔列。 我尝试使用 header = F 或 col.names = F 来消除标题,并尝试使用 sep = "\t" 来分隔列,但它无法识别命令。

如果有任何帮助,我将不胜感激。 谢谢, E.

根据所有建议,这是可以解决问题的更简单的代码:

#set 'working directory'
setwd('C:/Users/Elena/Desktop/DayCent_muvp_MODEL/DayCent_SourceData/soils_data/sitesoil_in')

#identify data frame from .csv file
sd <- read.csv('site_soil.csv', sep="\t", header=F, fill=F)

lapply(1:nrow(sd), 
       function(i) write.table(sd[i,],
                               file = paste0(sd[i,1], ".txt",collapse = ""),
                               row.names = FALSE, col.names = FALSE,
                               sep = "\t"
       ))

感谢大家的帮助。 E.

【问题讨论】:

检查 write.table - 您的方法将其再次保存为 .csv,这在您的情况下是不可取的。你能解释一下这个仅仅有用的拆分成数千个 .txt 文件的目的背后的意图吗? 谢谢 Christian,我试过了,但是如果我使用 write.table 而不是 write.csv,它会给我一个错误......这些是另一个代码生成模型文件的输入文件输入。后面的代码要求这些文件采用非常特定的格式才能识别信息。 您将需要调查当时给出的错误。 write.csvwrite.table 的包装器,如文档 (?write.table) 所述,并不打算变得灵活。根据我的经验,使用write.table 并手动指定所需的正确参数几乎总是更好,而不是使用write.csv 并希望它的参数是你需要的。 谢谢user5359531,我会按照你的建议检查参数,看看能不能找到错误的根源。 【参考方案1】:

我调整了你的代码:

lapply(1:nrow(sd),
    function(i) write.table(sd[i,],
                            file = paste0(sd[i,1],".txt",collapse = ""),
                            row.names = FALSE,
                            sep = "\t"
                            ))

【讨论】:

有效!谢谢!!为什么它以前不能识别 write.table ?现在我只需要弄清楚如何消除列名。再次感谢!【参考方案2】:

试试这个

dat <-"01001_r1,32.4327,-86.6190,0.65,0.20,0.15,1.33,5.47,8
01001_r2,32.4327,-86.6190,0.65,0.20,0.15,1.33,5.46,8
01001_r3,32.4327,-86.6190,0.80,0.15,0.05,1.33,5.23,10
01003_r1,30.4887,-87.6918,0.65,0.20,0.15,1.33,5.23,9
01003_r2,30.4887,-87.6918,0.80,0.15,0.05,1.33,5.25,9
01003_r3,30.4887,-87.6918,0.65,0.20,0.15,1.33,4.96,8
"


df <- read.delim(file = textConnection(dat), sep = ',', header = FALSE)

df
#         V1      V2       V3   V4   V5   V6   V7   V8 V9
# 1 01001_r1 32.4327 -86.6190 0.65 0.20 0.15 1.33 5.47  8
# 2 01001_r2 32.4327 -86.6190 0.65 0.20 0.15 1.33 5.46  8
# 3 01001_r3 32.4327 -86.6190 0.80 0.15 0.05 1.33 5.23 10
# 4 01003_r1 30.4887 -87.6918 0.65 0.20 0.15 1.33 5.23  9
# 5 01003_r2 30.4887 -87.6918 0.80 0.15 0.05 1.33 5.25  9
# 6 01003_r3 30.4887 -87.6918 0.65 0.20 0.15 1.33 4.96  8

output_file_base <- "soil_"
output_file_ext <- ".tsv"

for(i in seq(nrow(df)))
    output_file <- paste0(output_file_base, as.character(i), output_file_ext)
    dfi <- df[i, ]
    write.table(x = dfi, file = output_file, sep = '\t', quote = FALSE, col.names = FALSE, row.names = FALSE)

输出:

$ cat soil_6.tsv
01003_r3    30.4887 -87.6918    0.65    0.2 0.15    1.33    4.96    8

【讨论】:

再次感谢。我尝试转换为 df,它适用于有限的数据。问题是超过 9,000 行我最终得到一个 8,000 行代码...我试图找到一个更简单的解决方案... 我在 col.names 参数中缺少逗号!好笑。我意识到审查了您的代码,再次感谢您的帮助。 “问题在于,如果有超过 9,000 行,我最终会得到一个 8,000 行代码。”不确定您的意思是什么,我希望您没有将整个 CSV 文件内容嵌入到您的脚本中?您的原始帖子显示您正在将 CSV 直接读取到 df 中。我不清楚除此之外您还需要哪些其他代码行。 对不起@user5359531,我误解了你的回答。我明白你的意思了。感谢您的帮助。【参考方案3】:

这可能适用于您要完成的工作。

df  <-read.csv(text = "01001_r1,32.4327,-86.6190,0.65,0.20,0.15,1.33,5.47,8
01001_r2,32.4327,-86.6190,0.65,0.20,0.15,1.33,5.46,8
01001_r3,32.4327,-86.6190,0.80,0.15,0.05,1.33,5.23,10
01003_r1,30.4887,-87.6918,0.65,0.20,0.15,1.33,5.23,9
01003_r2,30.4887,-87.6918,0.80,0.15,0.05,1.33,5.25,9
01003_r3,30.4887,-87.6918,0.65,0.20,0.15,1.33,4.96,8",
stringsAsFactors = FALSE,
header = FALSE)


apply(df, 1, function(x)write.table(t(x), 
                                     file = paste0(x[1],".txt"), 
                                     sep = "\t", 
                                     quote = FALSE, 
                                     col.names = FALSE, 
                                     row.names = FALSE))

【讨论】:

谢谢马特。我尝试转换为 df,它适用于有限的数据。问题是,超过 9,000 行我最终得到一个 8,000 行代码...我试图找到一个更简单的解决方案...无论如何,我会保留您的代码以供以后使用,再次感谢! 这篇文章已经有一段时间了,但是你怎么能把这段代码修改成一个块而不是一行呢?即,20 行? 我可能会将数据帧拆分为 20 行数据帧的列表ldf &lt;- split(df, (as.numeric(rownames(df))-1) %/% 20) 然后使用列表上的 lapply 函数将每个数据帧写入它自己的文件。 lapply(ldf, function(x)write.table(x, file = paste0("Rows ", min(rownames(x)), " - ", max(rownames(x)),".txt"), sep = "\t", quote = FALSE, col.names = FALSE, row.names = FALSE))

以上是关于r - 将一个 csv 文件拆分为多个 txt 文件的主要内容,如果未能解决你的问题,请参考以下文章

根据列将大型 csv 文件拆分为多个文件

根据行值python将大型csv文件拆分为多个文件

Scala:我如何根据行数将数据帧拆分为多个 csv 文件

使用正则表达式将 txt 文件拆分为多个新文件

将数据拆分为训练/测试文件,以便为两个文件选择至少一个样本

将文件名拆分为名称,扩展名