2015-07-07 4 views
5

Я прочитал регулярные выражения и пакеты Hadley Wickham's stringr и dplyr, но не могу понять, как заставить это работать.Создайте новые переменные, основанные на определенных значениях

У меня есть данные об обращении с библиотекой в ​​кадре данных, с номером вызова в качестве символьной переменной. Я хотел бы взять начальные заглавные буквы и сделать новую переменную, а цифры между буквами и периодом - второй новой переменной.

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

Это не для меня ясно, что ваши данные выглядят точно. Можете ли вы опубликовать код, который генерирует структуру данных, с которой вы имеете дело? –

ответ

4

Используя пакет stringi, это будет один из вариантов. Так как ваша цель остается в начале строк, stri_extract_first() будет работать очень хорошо. [:alpha:]{1,} указывает последовательности алфавитов, которые содержат более одного алфавита. С помощью stri_extract_first() вы можете идентифицировать первую последовательность алфавитов. Аналогично, вы можете найти первую последовательность чисел с stri_extract_first(x, regex = "\\d{1,}").

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

Спасибо jazzurro, он отлично работает! Вот код, который я адаптировал для своего конкретного фрейма данных: circ_data: circ_data_new <- transform (circ_data, Call_Num_Alpha = (stri_extract_first (circ_data $ Call_Num, regex = "[: alpha:] {1,}"))) AND circ_data_new <- transform (circ_data_new, Call_Num_Number = (stri_extract_first (circ_data $ Call_Num, regex = "\\ d {1,}"))) –

+0

Была только одна небольшая проблема - когда она создавала новые переменные, она делала им оба фактора. Не могли бы вы предложить, как чтобы сделать первый тип символа, а второй - целочисленным типом? –

+0

@ConceptDelta Спасибо за ваш комментарий. Вы хотите использовать 'as.character()' и обернуть код. Например, 'alpha = as.character (stri_extract_first (x, regex = "[: alpha:] {1,}")) 'Надеюсь, это вам поможет. – jazzurro

2

насчет

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

Hi rawr. Благодарим за ваше предложение. Однако я закончил тем, что использовал джаззурро. –

2

Если вы хотите использовать stringr, решение вероятно, будет выглядеть примерно так:

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 

Я не думаю, что воткнув str_match() вызов в mutate() от dplyr стоит усилий, поэтому я просто оставлю это на этом. Или используйте rawr's solution.

+0

Привет, Клаус. Благодарим за ваше предложение. Однако я закончил тем, что использовал джаззурро. –

+0

Возможно, вы должны проверить его решение. –

2

Вы можете использовать strapply из пакета gsubfn:

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

Hi hwnd. Благодарим за ваше предложение. Однако я закончил тем, что использовал джаззурро. –

Смежные вопросы