将文本文件转换为数据框 R

Posted

技术标签:

【中文标题】将文本文件转换为数据框 R【英文标题】:Converting text file to data frame R 【发布时间】:2015-09-23 22:37:51 【问题描述】:

我知道这里有人问过类似的问题,但我仍然相信我的任务更复杂。

我有一个文本文件,其中包含来自项目 geonames.org 的信息,名为 MX.txt,其中数据排列如下:

MX  20158   Villas del Cobano   Aguascalientes  AGU Aguascalientes  
001      Aguascalientes 01  21.8495 -102.3052   1
MX  20158   Hacienda el Cobano  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01 21.8495  -102.3052   1
MX  20159   Alianza Ferrocarrilera  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.8495 -102.3052   1
MX  20159   Bosques del Prado Oriente   Aguascalientes  AGU Aguascalientes
001 Aguascalientes  01  21.8495 -102.3052   1
MX  20160   Francisco Guel Jimenez  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.7561 -102.305    1
MX  20160   Las Viñas INFONAVIT Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.7561 -102.305    1
MX  20164   Santa Anita 4a Sección  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.7561 -102.305    1

文件持续了几千行。

我想把它变成一个包含 12 个变量的数据框,其中像“Villas del Cobano”这样的字符串只是这样的一个条目:

V1  V2      V3                  V4              V5  V6
MX  20158   Villas del Cobano   Aguascalientes  AGU Aguascalientes  
V7  V8              V9  V10     V11         V12
001 Aguascalientes  01  21.8495 -102.3052   1
V1  V2      V3                  V4              V5  V6
MX  20158   Hacienda el Cobano  Aguascalientes  AGU Aguascalientes
V7  V8              V9  V10     V11         V12 
001 Aguascalientes  01 21.8495  -102.3052   1

我已经尝试过之前发布的答案,例如: Converting text file into data frame in R , converting multiple lines of text into a data frame

因为英语不是我的第一语言,如果我的问题不够清楚,我想通过评论部分回答问题,而不是得到否定标记。

提前致谢!

【问题讨论】:

这可能是一个愚蠢的问题,但您是否尝试过read.table()sep = "\t"?您能展示一下您尝试过的代码以及最终结果吗? 感谢您的快速回复!不,实际上我没有,当我不小心删除了除第一行之外的所有文件时,它似乎可以正常工作 现在它说:“扫描错误(文件,内容,nmax,sep,dec,quote,skip,nlines,na.strings,:第 67894 行没有 12 个元素” 刚刚编辑了这样一行,效果很好你想把这个写成答案,这样我就可以把它标记为已回答? @LJW 刚刚回到这个问题 - 看起来你在下面有一些很好的答案,所以我不会重复。很高兴你成功了! 【参考方案1】:

列之间的分隔符是制表符,然后用

data <- read.table(file="MX.txt", sep="\t", quote="", comment.char="")

地名数据存在问题。有时他们在地名中使用#。默认情况下,read.table 读作注释会丢弃该行的其余部分,因此您需要设置 comment.char=""

【讨论】:

【参考方案2】:

我提出了一个冗长的解决方案,可能会得到你想要的。简而言之,我使用从每个嵌套列表的开始和结束的已知距离来隔离“多部分名称”,将其连接起来,并将其作为列输入到其他数据中。

函数 splitAt 来自R split numeric vector at position。

#Support functions
splitAt <- function(x, pos) unname(split(x, cumsum(seq_along(x) %in% pos)))
extractplace <- function(x) 
  len <- length(x)
  place0 <- x[-1*c(1:2,(len-8):len)]
  place <- paste(place0, collapse=" ")

extractother <- function(x) 
  len <- length(x)
  other <- x[c(1:2,(len-8):len)]


#initital data processing
elems <- scan(file="mx.txt", what="list") #creates a vector of all elements in your txt file
inds <- grep(pattern="MX", elems) #finds indices of "MX", which starts every nested list
lists <- splitAt(elems, inds) #creates a list of nested list

#create the matrix you want
placevector <- sapply(lists, function(x) extractplace(x)) #vector of multipart names
othermatrix <- t(sapply(lists, function(x) extractother(x))) #matrix of remaining data
fullmatrix <- cbind(othermatrix[,1:2],placevector,othermatrix[,3:11]) #inserts multipart names in matrix
colnames(fullmatrix) <- paste("V",1:12, sep="")

fullmatrix 

【讨论】:

对不起,反馈迟了,第一个答案实际上解决了我的问题,但你的问题是一个非常有趣/逻辑的解决方案。谢谢你!【参考方案3】:

这假设其余数据看起来像这个数据。我不得不做很多清洁工作(即gsubing):

代码:

vect <- unlist(Map(function(x, y) paste(x, y), dat[c(T, F)], dat[c(F, T)]), 
    use.names = FALSE)
read.table(text=gsub("\\s2,", ", ", gsub("(\\s)(\\d2,)", "  \\2", 
    gsub("(\\d2,|[A-Z]+)\\s+", "\\1  ", vect))), sep=",")

便于阅读的数据:

dat <- readLines(n=14)
MX  20158   Villas del Cobano   Aguascalientes  AGU Aguascalientes  
001      Aguascalientes 01  21.8495 -102.3052   1
MX  20158   Hacienda el Cobano  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01 21.8495  -102.3052   1
MX  20159   Alianza Ferrocarrilera  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.8495 -102.3052   1
MX  20159   Bosques del Prado Oriente   Aguascalientes  AGU Aguascalientes
001 Aguascalientes  01  21.8495 -102.3052   1
MX  20160   Francisco Guel Jimenez  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.7561 -102.305    1
MX  20160   Las Viñas INFONAVIT Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.7561 -102.305    1
MX  20164   Santa Anita 4a Sección  Aguascalientes  AGU Aguascalientes  
001 Aguascalientes  01  21.7561 -102.305    1

【讨论】:

以上是关于将文本文件转换为数据框 R的主要内容,如果未能解决你的问题,请参考以下文章

将pyspark数据框写入文本文件

不使用 databricks API 将数据框保存为文本文件

无法将带有字符串的文本文件转换为 R 中每行一个字符的列

使用R将PDF文件转换为文本文件进行文本挖掘

读取存储在文本文件中的字典并转换为熊猫数据框[重复]

C++如何将一个存有数据的文本文件转换为二进制文件?