如何在 R 中读取具有不同列数的 CSV 文件
Posted
技术标签:
【中文标题】如何在 R 中读取具有不同列数的 CSV 文件【英文标题】:How can you read a CSV file in R with different number of columns 【发布时间】:2013-09-26 04:18:42 【问题描述】:我有一个稀疏数据集,它的列数长度各不相同,采用 csv 格式。这是文件文本的示例。
12223, University
12227, bridge, Sky
12828, Sunset
13801, Ground
14853, Tranceamerica
14854, San Francisco
15595, shibuya, Shrine
16126, fog, San Francisco
16520, California, ocean, summer, golden gate, beach, San Francisco
当我使用时
read.csv("data.txt", header = F)
R 会将数据集解释为具有 3 列,因为大小是根据前 5 行确定的。无论如何强制 r 将数据放在更多列中?
【问题讨论】:
你知道你的数据集中的最大列数吗? 是的,最大列数已知 我的直觉是在read.table
中指定colClasses
参数(具有最大列数)并结合fill = TRUE
应该读入文件。
@BlueMagister 我也是这么想的,但是没用。
你能不能用 2 行和正确的列数创建一个虚拟的 data.frame
,然后将 rbind
文本文件添加到它?
【参考方案1】:
我遇到了类似的挑战,但 Blue Magister 的回答中的 count.fields
不起作用,可能是因为字段内的逗号与 sep=","
冲突。此外,列数因文件而异。
所以我只是在read.table
中定义了多余的col.names
(在我的情况下100就足够了),然后我使用which(!is.na())
去除多余的列。
dat <- read.table("path/to/file.csv", col.names = paste("V",1:100), fill = T, sep = ",")
dat <- dat[,which(!is.na(dat[1,]))]
【讨论】:
【参考方案2】:试试这个,它更有活力..
readVariableWidthFile <- function(filePath)
con <-file(filePath)
lines<- readLines(con)
close(con)
slines <- strsplit(lines,",")
colCount <- max(unlist(lapply(slines, length)))
FileContent <- read.csv(filePath,
header = FALSE,
col.names = paste0("V",seq_len(colCount)),
fill = TRUE)
return(FileContent)
【讨论】:
请为您的答案添加更多解释。您的答案在当前接受的答案中没有添加什么? 我同意这更动态,因为它允许您循环通过csv
s 而无需指定列数【参考方案3】:
在?read.table
文档的深处有以下内容:
数据列的数量是通过查看前五个来确定的 输入行(如果文件少于五行,则为整个文件),或 从
col.names
的长度开始,如果它被指定并且更长。这 如果fill
或blank.lines.skip are true
可能是错误的,所以 如有必要,请指定col.names
(如“示例”中所示)。
因此,让我们将 col.names
定义为长度 X(其中 X 是数据集中的最大字段数),并设置 fill = TRUE
:
dat <- textConnection("12223, University
12227, bridge, Sky
12828, Sunset
13801, Ground
14853, Tranceamerica
14854, San Francisco
15595, shibuya, Shrine
16126, fog, San Francisco
16520, California, ocean, summer, golden gate, beach, San Francisco")
read.table(dat, header = FALSE, sep = ",",
col.names = paste0("V",seq_len(7)), fill = TRUE)
V1 V2 V3 V4 V5 V6 V7
1 12223 University
2 12227 bridge Sky
3 12828 Sunset
4 13801 Ground
5 14853 Tranceamerica
6 14854 San Francisco
7 15595 shibuya Shrine
8 16126 fog San Francisco
9 16520 California ocean summer golden gate beach San Francisco
如果不知道最大字段数,可以使用漂亮的实用函数count.fields
(我在read.table
示例代码中找到):
count.fields(dat, sep = ',')
# [1] 2 3 2 2 2 2 3 3 7
max(count.fields(dat, sep = ','))
# [1] 7
可能有帮助的相关阅读:Only read limited number of columns in R
【讨论】:
谢谢,非常有帮助 这花了我很长时间。非常感谢!【参考方案4】:这似乎确实有效(遵循@BlueMagister 的建议):
tt <- read.table("~/Downloads/tmp.csv", fill=TRUE, header=FALSE,
sep=",", colClasses=c("numeric", rep("character", 6)))
names(tt) <- paste("V", 1:7, sep="")
V1 V2 V3 V4 V5 V6 V7
1 12223 University
2 12227 bridge Sky
3 12828 Sunset
4 13801 Ground
5 14853 Tranceamerica
6 14854 San Francisco
7 15595 shibuya Shrine
8 16126 fog San Francisco
9 16520 California ocean summer golden gate beach San Francisco
【讨论】:
我刚刚又试了一次。如果我使用text
参数,这将不起作用。
啊哈..这就是原因..很高兴知道这种差异!感谢您的回信。【参考方案5】:
你可以这样读取数据:
dat <- textConnection("12223, University
12227, bridge, Sky
12828, Sunset
13801, Ground
14853, Tranceamerica
14854, San Francisco
15595, shibuya, Shrine
16126, fog, San Francisco
16520, California, ocean, summer, golden gate, beach, San Francisco")
dat <- readLines(dat)
dat <- strsplit(dat, ",")
这会产生一个列表。
【讨论】:
我拥有的数据集很大。我正在寻找一种无需复制和粘贴文件内容的解决方案。我知道我可以在 ruby 中打开文件并在一行中搜索最大数量的逗号并将该行移动到第一行。然后我可以在 R 中打开文件,一切都会得到解决,但我希望在 R 中有一个简单的解决方案。 好吧,显然你会使用文件连接(阅读?connection
)。但我无权访问您的文件...
@CompChemist 将您的文件对象 (data.txt
) 替换为 dat
。 textConnection
用于快速读取您的示例文件。
谢谢!我现在知道了。感谢您的帮助以上是关于如何在 R 中读取具有不同列数的 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章
自动 CSV 文件生成,在 Oracle 10g 中具有不同列数的两个标题级别的标题
如何使用 vim 命令或 sed/awk 命令将具有不同列数的行分隔到另一个文件中? [关闭]
我们如何在 Spark 中使用 Dataframes(由 structtype 方法创建)合并具有不同列数的 2 个表?