2017-08-17 1 views
1

Mon fichier de données contient une variété de chaînes. Voir l'exemple df:Comment isoler un mot à côté d'un mot spécifié

strings <- c("Average complications and higher payment", 
     "Average complications and average payment", 
     "Average complications and lower payment", 
     "Average mortality and higher payment", 
     "Better mortality and average payment") 
    df <- data.frame(strings, stringsAsFactors = F) 

J'aimerais isoler le premier mot dans la phrase et la deuxième à la dernière. L'avant-dernier précède toujours le mot «paiement».

est ici à quoi ressemblerait mon désiré df comme:

strings <- c("Average complications and higher payment", 
     "Average complications and average payment", 
     "Average complications and lower payment", 
     "Average mortality and higher payment", 
     "Better mortality and average payment") 
QualityWord <- c("Average","Average","Average","Average","Better") 
PaymentWord <- c("Higher","Average","Lower","Higher","Average") 
desireddf <- data.frame(strings, QualityWord, PaymentWord, stringsAsFactors = F) 

Les chaînes résultantes ne doivent pas nécessairement être sensible à la casse. Je suis capable d'écrire du code pour obtenir le premier mot d'une phrase (divisé sur l'espace) mais je n'arrive pas à comprendre comment tirer un mot à gauche (ou à droite, d'ailleurs) d'une référence mot, qui est "paiement" dans ce cas.

Répondre

1
df$QualityWord = sub("(\\w+).*?$", "\\1", df$strings) 
df$PaymentWord = sub(".*?(\\w+) payment$", "\\1", df$strings) 

df 
#>          strings QualityWord PaymentWord 
#> 1 Average complications and higher payment  Average  higher 
#> 2 Average complications and average payment  Average  average 
#> 3 Average complications and lower payment  Average  lower 
#> 4  Average mortality and higher payment  Average  higher 
#> 5  Better mortality and average payment  Better  average 

Les termes regex expliqué:

  • (\\w+) = correspondre à un caractère de mot une ou plusieurs fois, capturé en tant que groupe
  • .*? = correspondre à quelque chose, non avidement
  • payment = correspondre à un espace, puis les personnages payment
  • $ = correspond à la fin de la chaîne.
  • \\1 = substituer le motif à ce qui était dans le premier groupe.
0

Avec strsplit, head et tail fonctions:

outDF = do.call(rbind,lapply(DF$strings,function(x) { 

#split string 
strObj = unlist(strsplit(x,split=" ")) 

#outputDF 
data.frame(strings = x,QualityWord=head(strObj,1),PaymentWord= head(tail(strObj,2),1),stringsAsFactors=FALSE) 

})) 

outDF 
#         strings QualityWord PaymentWord 
#1 Average complications and higher payment  Average  higher 
#2 Average complications and average payment  Average  average 
#3 Average complications and lower payment  Average  lower 
#4  Average mortality and higher payment  Average  higher 
#5  Better mortality and average payment  Better  average 

OU:

Avec dplyr et une fonction personnalisée:

customFn = function(x) { 
strObj = unlist(strsplit(x,split=" ")); 
outputDF = data.frame(strings = x,QualityWord=head(strObj,1),PaymentWord= head(tail(strObj,2),1),stringsAsFactors=FALSE); 
} 

DF %>% 
dplyr::rowwise() %>% 
dplyr::do(customFn(.$strings)) 
1

Nous pouvons utiliser extract de tidyr

library(tidyverse) 
df %>% 
    extract(strings, into = c("QaulityWord", "PaymentWord"), 
      "^(\\w+).*\\b(\\w+)\\s+\\w+$", remove = FALSE) 
#         strings QaulityWord PaymentWord 
#1 Average complications and higher payment  Average  higher 
#2 Average complications and average payment  Average  average 
#3 Average complications and lower payment  Average  lower 
#4  Average mortality and higher payment  Average  higher 
#5  Better mortality and average payment  Better  average