2017-01-25 1 views
1

Ich habe profitiert von SO, eine ganze Weile jetzt und jetzt beschlossen, sich anzumelden und versuchen, a) anderen zu helfen und b) Hilfe von tollen Jungs :)Extrahieren drei Zahlen aus einer Zeichenfolge (fehlende Nummer?)

Also meine Frage kommen, ich habe Vektor aus einem Datenrahmen extrahiert, die wie folgt aussieht (nur kleine Teilmenge der Daten): um

cho <- c("[M-H]: C4H4O2", 
"[M+Hac-H]: C5H10O6", 
"[M-H]: C6H4O3", 
"[M+Fa-H]: C7H6O", 
"[M-H]: C9H8O3", 
"[M-H]: C18H30O3); 

nun aus diesem Vektor ich die Zahlen extrahieren möchten die Anzahl der Atome "C", "H" und "O" erhalten:

temp <- strsplit(cho, "[^[:digit:]]"); 
temp <- as.numeric(unlist(temp)); 

#remove NAs 
temp <- temp[!is.na(temp)]; 

#split into three column matrix and convert to df to merge with original df 
temp <- as.data.frame(matrix(temp, ncol = 3, byrow = T)); 

In diesem Fall recycelt R die Daten, um die Matrix zu generieren, in meinem Fall für den größeren Datensatz ist der erzeugte Vektor lang genug und die Matrix wird erzeugt, aber es ist ein Chaos; Dies liegt an Fällen wie "[M+Fa-H]: C7H6O" wo nur zwei Zahlen extrahiert werden können; Wie ist es möglich, eine "1" nach einem "O" zu bekommen, so dass drei statt zwei Zahlen extrahiert werden können? Gibt es einen Workaround dafür?

Vielen Dank im Voraus für Ihre Hilfe!

Antwort

2

Wir können str_extract_all verwenden. Verwenden Sie die regex Lookarounds eine oder mehrere Zahlen übereinstimmen (\\d+), die entweder folgt einem C oder H oder O, extrahieren, diese Zahlen in einem list und konvertieren integer

library(stringr) 
lst <- lapply(str_extract_all(cho, "(?<=C|H|O)\\d+"), as.integer) 

Oder ein base R Option ist

read.csv(text=sub(".*C?(\\d+)H?(\\d+)O?(\\d*).*", 
       "\\1,\\2,\\3", cho), header=FALSE, fill=TRUE) 
+1

großartig! auch wo Wert fehlt, müssen wir möglicherweise einfügen 1 –

+0

auch könnten Sie erklären, die Regex Schritt-für-Schritt verwendet –

+1

viel kürzer Code als meins, vielen Dank! 'Base R' Lösung ist perfekt für mich, nur NAs zu ersetzen! – munirbe

Verwandte Themen