簡體   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