2015-07-07 2 views
5

Ich lese auf regulären Ausdrücken und Hadley Wickhams stringr und dplyr Pakete, aber kann nicht herausfinden, wie man dies zum Funktionieren bringt.Erstellen neuer Variablen basierend auf bestimmten Werten

Ich habe Bibliotheksumlaufdaten in einem Datenrahmen, mit der Rufnummer als Zeichenvariable. Ich möchte die Anfangsbuchstaben verwenden und daraus eine neue Variable und die Ziffern zwischen den Buchstaben und der Periode zu einer zweiten neuen Variable machen.

Call_Num 
HV5822.H4 C47 Circulating Collection, 3rd Floor 
QE511.4 .G53 1982 Circulating Collection, 3rd Floor 
TL515 .M63 Circulating Collection, 3rd Floor 
D753 .F4 Circulating Collection, 3rd Floor 
DB89.F7 D4 Circulating Collection, 3rd Floor 
+0

Es ist mir nicht klar, was Ihre Daten genau aussehen. Können Sie Code posten, der die Art von Datenrahmen erzeugt, mit der Sie es zu tun haben? –

Antwort

4

Verwenden Sie das -Paket, dies wäre eine Option. Da Ihr Ziel am Anfang der Strings bleibt, würde stri_extract_first() ziemlich gut funktionieren. [:alpha:]{1,} gibt alphabetische Sequenzen an, die mehr als ein Alphabet enthalten. Mit stri_extract_first() können Sie die erste Alphabetsequenz identifizieren. Ebenso können Sie die erste Zahlenfolge mit stri_extract_first(x, regex = "\\d{1,}") finden.

x <- c("HV5822.H4 C47 Circulating Collection, 3rd Floor", 
     "QE511.4 .G53 1982 Circulating Collection, 3rd Floor", 
     "TL515 .M63 Circulating Collection, 3rd Floor", 
     "D753 .F4 Circulating Collection, 3rd Floor", 
     "DB89.F7 D4 Circulating Collection, 3rd Floor") 

library(stringi) 

data.frame(alpha = stri_extract_first(x, regex = "[:alpha:]{1,}"), 
      number = stri_extract_first(x, regex = "\\d{1,}")) 

# alpha number 
#1 HV 5822 
#2 QE 511 
#3 TL 515 
#4  D 753 
#5 DB  89 
+0

Danke jazzurro, es funktioniert super! Hier ist der Code, den ich für meinen spezifischen Datenrahmen namens "circ_data: circ_data_new <- transform (circ_data, Call_Num_Alpha = (stri_extract_first (circ_data $ Call_Num, regex =" [: alpha:] {1,} "))) und circ_data_new <- transform (circ_data_new, Call_Num_Number = (stri_extract_first (circ_data $ Call_Num, regex = "\\ d {1,}"))) –

+0

Es gab nur ein kleines Problem - wenn es neue Variablen erstellt hat, hat es beide Faktoren beeinflusst um den ersten einen Zeichentyp und die zweite einen ganzzahligen Typ zu machen? –

+0

@ConceptDelta Danke für Ihren Kommentar. Sie wollen 'as.character()' verwenden und den Code umbrechen. Zum Beispiel, alpha = as.character (stri_extract_first (x, regex = "[: alpha:] {1,}")) ". Hoffe, das hilft dir. – jazzurro

2

was

rl <- read.table(header = TRUE, text = "Call_Num 
'HV5822.H4 C47 Circulating Collection, 3rd Floor' 
       'QE511.4 .G53 1982 Circulating Collection, 3rd Floor' 
       'TL515 .M63 Circulating Collection, 3rd Floor' 
       'D753 .F4 Circulating Collection, 3rd Floor' 
       'DB89.F7 D4 Circulating Collection, 3rd Floor'", 
       stringsAsFactors = FALSE) 
cbind(rl, read.table(text = gsub('([A-Z]+)([0-9]+).*', '\\1 \\2', rl$Call_Num))) 

#            Call_Num V1 V2 
# 1  HV5822.H4 C47 Circulating Collection, 3rd Floor HV 5822 
# 2 QE511.4 .G53 1982 Circulating Collection, 3rd Floor QE 511 
# 3  TL515 .M63 Circulating Collection, 3rd Floor TL 515 
# 4   D753 .F4 Circulating Collection, 3rd Floor D 753 
# 5  DB89.F7 D4 Circulating Collection, 3rd Floor DB 89 
+0

Hallo rawr. Danke für deinen Vorschlag. Am Ende habe ich den von jazzurro benutzt. –

2

Wenn Sie stringr verwenden, wäre die Lösung wahrscheinlich so etwas wie folgt aussehen:

df <- data.frame(Call_Num = c("HV5822.H4 C47 Circulating Collection, 3rd Floor", "QE511.4 .G53 1982 Circulating Collection, 3rd Floor", "TL515 .M63 Circulating Collection, 3rd Floor", "D753 .F4 Circulating Collection, 3rd Floor", "DB89.F7 D4 Circulating Collection, 3rd Floor")) 

require(stringr) 

matches = str_match(df$Call_Num, "([A-Z]+)(\\d+)\\s*\\.") 
df2 <- data.frame(df, letter=matches[,2], number=matches[,3]) 
df2 
##             Call_Num letter number 
## 1  HV5822.H4 C47 Circulating Collection, 3rd Floor  HV 5822 
## 2 QE511.4 .G53 1982 Circulating Collection, 3rd Floor  QE 511 
## 3  TL515 .M63 Circulating Collection, 3rd Floor  TL 515 
## 4   D753 .F4 Circulating Collection, 3rd Floor  D 753 
## 5  DB89.F7 D4 Circulating Collection, 3rd Floor  DB  89 

Ich glaube nicht, dass das Festhalten str_match() Anruf in mutate() von dplyr ist die Mühe wert, also würde ich es einfach dabei belassen. Oder verwenden Sie rawr's solution.

+0

Hallo Claus. Danke für deinen Vorschlag. Am Ende habe ich den von jazzurro benutzt. –

+0

Sie sollten wahrscheinlich seine Lösung markieren. –

2

können Sie strapply vom gsubfn Paket verwenden:

library(gsubfn) 

m <- strapply(as.character(df$Call_Num), '^([A-Z]+)(\\d+)', 
    ~ c(id = x, num = y), simplify = rbind) 

X <- as.data.frame(m, stringsAsFactors = FALSE) 

# id num 
# 1 HV 5822 
# 2 QE 511 
# 3 TL 515 
# 4 D 753 
# 5 DB 89 
+0

Hallo hwnd. Danke für deinen Vorschlag. Am Ende habe ich den von jazzurro benutzt. –