繁体   English   中英

用r解析非结构化文件

[英]parsing unstructured files with r

我正在尝试使用R解析此非结构化文件

ftp://ftp.fu-berlin.de/pub/misc/movies/database/genres.list.gz

Deadpoint (2012)     Action
Deadpoint (2012)     Drama
Deadpoint (2012)     Short
Deadpoint (2016)     Action
Deadpoint (2016)     Adventure
Deadpoint (2016)     Drama
Deadpoint (2016)     Horror
Deadpoint (2016)     Short
Deadpool (2013) (VG)     Action
Deadpool (2013) (VG)     Comedy
Deadpool (2013) (VG)     Fantasy
Deadpool (2016)      Action
Deadpool (2016)      Adventure
Deadpool (2016)      Comedy
Deadpool (2016)      Romance
Deadpool (2016)      Sci-Fi
Deadpool 2 (2018)     Action
Deadpool 2 (2018)     Adventure
Deadpool 2 (2018)     Comedy
Deadpool 2 (2018)     Fantasy

我将示例作为代码发布,因为无法在此处以正确的格式发布示例,但是它是电影名称(包括年份),可变数量的标签和一个单词类型。

我想在第一列中捕获电影标题,在最后一列中捕获流派。 使用正则表达式,我会这样:

^(.*?)\t+(\S+)$

我试图从gzip和gsub("\\t+","\\t",lines)读取read_lines gsub("\\t+","\\t",lines)但是read.table无法读取已清理的变量。

read.table(lines, header = FALSE, sep = "\t", quote = "\"", fill = TRUE, comment.char = "", skip=380)

使用上面的代码,根据该行具有的选项卡数,我在第一列中获得了电影标题,在另外6列中获得了流派。 关于替代品的任何想法如何做到这一点。

假设您将文件读入名为line,的数组中line,尝试以下操作。 它通过调整R的一些小怪癖来实现您的正则表达式。 您的正则表达式没有考虑到某些电影在年份和类型之间存在某些问题(例如“天使之城(2011){{SUSPENDED}}戏剧”),但这种情况很少发生。

line <- gsub('\"', '', line)     # delete quotes
line <- gsub('\\t',' ', line)    # tabs into spaces
line <- gsub(' {2,}', ' ', line) # delete extra spaces
line <- regmatches(line,regexpr('^(.*?)\\s(\\S+)$',line))

它需要一段时间才能运行230万行,但它确实有效

以下代码将数据分为两列。

我使用tibble和tidyr拆分数据。

library(readr)
library(tidyr)
library(tibble)

data <- read_lines("genres.list.gz", skip = 380)

data <- gsub('\"', '', data)     # delete quotes
data <- gsub('\\t+','~', data)    # replace tabs with a ~ 


movies <- data %>% 
  # turn into tibble data_frame. avoids stringsAsFactors = FALSE 
  # name column movie 
  data_frame(movie = .) %>%  
  # split movie column based on "~"
  separate(movie, c("movie", "genre"), "~", extra = "merge")

#clean up workspace
rm(lines) 

head(movies)
# A tibble: 6 x 2
                     movie       genre
                     <chr>       <chr>
1            !Next? (1994) Documentary
2         #1 Single (2006)  Reality-TV
3    #15SecondScare (2015)      Horror
4    #15SecondScare (2015)       Short
5    #15SecondScare (2015)    Thriller
6 #1MinuteNightmare (2014)      Horror

我想出了以下解决方案

genres<-read.table(genres.list.gz, header = FALSE, sep = "\t", quote = "\"", fill = TRUE, comment.char = "", skip=starts+2)
x<-paste(genres[,2],genres[,3],genres[,4],genres[,5],genres[,6],genres[,7])
x<-gsub("\\s+", "", x)
genres[,2:7]<-NULL
genres[,2]<-x
names(genres) <- c("Title", "Genre")

首先,我创建了一个向量x,并将所有类型列连接在一起;其次,我从所有条目中删除了所有空白

然后我从流派data.frame中删除所有列,并将x设置为第二列

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM