2017-01-26 3 views
0

J'ai le texte intégral de l'article. Je veux extraire quelques informations (comme l'année ou le mois) pour l'analyser.Dans R: extraire des informations dans une phrase de texte

Et À titre d'exemple de la structure du texte de l'article,

4 Décembre, 2016 dimanche, LONGUEUR: (longueur du texte principal), HEADLINE: (le titre de l'article), BYLINE: (journaliste nom), CORPS: (texte principal)

Je présente tous les textes en une ligne par un article (donc je pense qu'il peut être possible que traiter la structure de l'article sous forme de chaîne)

In.. ce format, comment puis-je extraire la LONGUEUR, HEADL INE, BYLINE valeurs et faire le cadre de données?

Je pense que cela pourrait être possible Si vous utilisez l'expression régulière correctement, mais je ne sais pas exactement.

+1

Certainement regex, voir? regexpr ou [regexpr] (https://stat.ethz.ch/R-manual/R-devel/library/base/html/regex.html) –

+1

Merci pour votre commentaire! –

Répondre

0

J'espère que la solution est utile ci-dessous. Je suis sûr que des moyens plus efficaces sont possibles, consultez gsub, grep, stringr.


DF<-data.frame(do.call(rbind, strsplit(x, ",", fixed=TRUE))) 
DF$X1 <- paste(DF$X1,DF$X2, sep = ",")  
new_df<-as.data.frame(lapply(DF, function(x) gsub(".*:", "", x))) 
new_df<-subset(new_df, select = -X2) 
colnames(new_df)<-c("Date","Length","Headline","ByLine","Other") 
new_df 

sortie

     Date  Length           Headline 
1 December 4, 2016 Sunday 1070 words Korea presents new farm development model globally 
2 Noveember 10, 2016 Friday 1070 words Korea presents new farm development model globally 
      ByLine Other 
1 By Yoon Ja-young ~~~ 
2 By Yoon Ja-young ~~~ 

données

x<- c("December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea 
     presents new farm development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~", 
     "Noveember 10, 2016 Friday, LENGTH: 1070 words, HEADLINE: Korea 
     presents new farm development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~") 

upd mangé: Comme mentionné dans les commentaires par @ G.Grothendieck, changé la solution pour afficher les champs en colonnes.

0

Cela pourrait être un début: Utilisez strsplit pour extraire les pièces dont vous avez besoin. Ce code est un peu compliqué, mais cela fonctionne:

sentence <- "December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm development model globally, BYLINE: By Yoon Ja-young" 

Date <- as.character(sapply(strsplit(sentence, "LENGTH"), "[[",1)) 
Rows <- as.character(sapply(strsplit(sentence, "LENGTH"), "[[",2)) 
Length <- gsub(":","", as.character(sapply(strsplit(Rows, ","), "[[",1))) 
Headline <- as.character(sapply(strsplit(as.character(sapply(strsplit(Rows, ","), "[[",2)), ":"), "[[",2)) 
Byline <- as.character(sapply(strsplit(as.character(sapply(strsplit(Rows, ","), "[[",3)), ":"), "[[",2)) 

se rassemblent ensuite les rangs d'une trame de données:

Df <- data.frame(Date, Length, Headline, Byline) 
1

Définissez d'abord les données de test de manière reproductible - nous avons utilisé deux instances des données présentées dans la question. Nous notons que la partie délicate est que chaque enregistrement dépasse plus d'une ligne dans la question.

Lire dans Lines - avec les données réelles remplacer textConnection(Lines), qui est de garder le code autonome, avec "myfile.txt", par exemple.

Ensuite, le premier sub insère un espace au début de chaque ligne et la seconde remplace tout jusqu'au LONGUEUR: sur une ligne contenant LONGUEUR: avec saut de ligne, DATE:, la date et LENGTH:. Le gsub insère un retour à la ligne avant chaque mot clé, et le paste le regroupe en une seule grande chaîne séparée par une nouvelle ligne. strsplit le sépare de nouveau afin que les nouvelles lignes que nous avons ajoutées sont effectuées.

Les données sont maintenant au format DCF, donc nous pouvons le lire en utilisant read.dcf. Le format DCF sépare les enregistrements par une ou plusieurs lignes vides et démarre chaque champ avec le nom de champ suivi d'un signe deux-points et d'un espace suivi de la valeur. La valeur peut s'exécuter sur plusieurs lignes à condition que les lignes suivantes soient indentées, par ex. Commencez avec un espace.

Ceci donne une matrice avec les 5 colonnes indiquées. La dernière sub supprime les virgules à la fin de chaque élément et la dernière gsub remplace les nouvelles lignes par des espaces.

Notez que nous avons placé les champs dans des colonnes, ce qui correspond normalement à la façon dont les données sont représentées dans R, mais si vous le souhaitez vraiment dans les lignes, utilisez t(dcf).

# test data 

Lines <- "December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm 
development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~ 
December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm 
development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~" 

# code 

L0 <- readLines(textConnection(Lines)) 
L <- sub("^", " ", L0) 
L <- sub("(.*) LENGTH:", "\nDATE: \\1 LENGTH:", L) 
L <- gsub("(\\w+:)", "\n\\1", L) 
L <- paste(L, collapse = "\n") 
L <- unlist(strsplit(L, "\n")) 
dcf <- read.dcf(textConnection(L)) 
dcf[] <- sub(",$", "", dcf) 
dcf[] <- gsub("\n", " ", dcf) 

Cela donne la matrice de caractères 5 colonne suivante:

> dcf 

    DATE      LENGTH  
[1,] "December 4, 2016 Sunday" "1070 words" 
[2,] "December 4, 2016 Sunday" "1070 words" 
    HEADLINE            BYLINE    
[1,] "Korea presents new farm development model globally" "By Yoon Ja-young" 
[2,] "Korea presents new farm development model globally" "By Yoon Ja-young" 
    BODY 
[1,] "~~~" 
[2,] "~~~" 

Mise à jour: Date ajoutée à la production.

+0

Les colonnes ont plus de sens que les lignes. belle solution. – user5249203

+1

Normalement, dans le traitement des données, les champs sont des colonnes et non des lignes. –

0

Voici une réponse qui utilise le fractionnement des chaînes et un peu de regex dans le paquet R de base. Tant que les données sont toujours dans le format indiqué, cela fonctionnera.

data <- "December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~" 

textParse <- function(dat){ 
    tmp <- strsplit(dat, ', ')[[1]] 

    time <- as.Date(paste(tmp[1:2], collapse = ' '), format="%B %d %Y") 

    len <- strsplit(gsub(".*LENGTH: (\\d+)", "\\1", dat), " ")[[1]][1] 

    headline <- paste(strsplit(tmp[4], ' ')[[1]][2:length(strsplit(tmp[4], ' ')[[1]])], collapse = ' ') 

    byline <- paste(strsplit(tmp[5], ' ')[[1]][3:length(strsplit(tmp[5], ' ')[[1]])], collapse = ' ') 

    body <- paste(strsplit(tmp[6], ' ')[[1]][2:length(strsplit(tmp[6], ' ')[[1]])], collapse = ' ') 

    return(as.data.frame(cbind(time, len, headline, byline, body))) 
} 

textParse(data) 

Sortie:

time len           headline  byline 
1 17139 1070 Korea presents new farm development model globally Yoon Ja-young 
    body 
1 ~~~ 

modifier: Notez que le temps en R est représenté comme un entier de "le nombre de jours écoulés depuis 1970-01-01" R: Date-time Conversion