2015-06-02 2 views
3

У меня есть список кодов во втором столбце таблицы, и я хочу извлечь некоторые элементы каждого кода, а затем сохранить их в новых столбцах, связанных с каждым из коды. Каждый код состоит из букв, за которыми следуют некоторые цифры. Буквы P, F, I, R, C повторяются с одинаковым порядком во всех кодах, но количество цифр меняется в каждом коде.Как разбить строку между двумя символами на подгруппы в R

Например: рассмотрит коду, как показано ниже:

P1F2I235R15C145 P1 F2 I23 R15 C145 
P24F1I12R124C96 P24 F1 I12 R124 C96 

так, таким образом, я могу разделить каждый код на его составляет субкоды, и хранить эти компоненты в новые столбцы в одной таблице. благодаря

+4

Если буквы всегда повторяется в том же порядке, то есть не существует высокая избыточность данных? Почему бы вам не использовать их вместо имен столбцов? – A5C1D2H2I1M1N2O1R2T1

+0

Подкоды фактически являются значениями переменных (с категориальными кодами), поэтому мне нужно, чтобы они хранились перед каждым исходным кодом по мере его запроса. все значения, начинающиеся с P, являются мерами, связанными с переменной P, и все значения после F являются мерами для одного и того же индивида, связанного с переменной F и т. д. – ashkan

ответ

3

Попробуйте это:

#simulate your data frame 
df<-data.frame(code=c("P1F2I235R15C145","P24F1I12R124C96"),stringsAsFactors=FALSE) 
#split the columns 
cbind(df,do.call(rbind,regmatches(df$code,gregexpr("[PFIRC][0-9]+",df$code)))) 
#    code 1 2 3 4 5 
#1 P1F2I235R15C145 P1 F2 I235 R15 C145 
#2 P24F1I12R124C96 P24 F1 I12 R124 C96 

Что @AnandaMatho предложил в комментарии было дать письмо перед кодом уйти и назвать столбцы соответственно. Нечто подобное:

res<-cbind(df,do.call(rbind,regmatches(df$code,gregexpr("(?<=[PFIRC])[0-9]+",df$code,perl=TRUE)))) 
names(res)<-c("Code","P","F","I","R","C") 
#    Code P F I R C 
#1 P1F2I235R15C145 1 2 235 15 145 
#2 P24F1I12R124C96 24 1 12 124 96 
+1

Оба варианта приятные Никола. +1 :-) – A5C1D2H2I1M1N2O1R2T1

+0

Ty, высоко оценили! – nicola

4

Вот возможный stringi решение

library(stringi) 
x <- c("P1F2I235R15C145","P24F1I12R124C96") 
res <- stri_split_regex(x,"(?=([A-Za-z]=?))",perl = TRUE,simplify = TRUE,omit_empty = TRUE) 
cbind.data.frame(x, res) 
#     x 1 2 3 4 5 
# 1 P1F2I235R15C145 P1 F2 I235 R15 C145 
# 2 P24F1I12R124C96 P24 F1 I12 R124 C96 
1

data.table решение:

library(data.table) 
dt<-data.table(code=c("P1F2I235R15C145","P24F1I12R124C96")) 
dt[,c("P","F","I","R","C"):= 
    lapply(c("P","F","I","R","C"), 
      function(x)regmatches(code,regexpr(paste0(x,"[0-9]+"),code)))] 

> dt 
       code P F I R C 
1: P1F2I235R15C145 P1 F2 I235 R15 C145 
2: P24F1I12R124C96 P24 F1 I12 R124 C96 

И если вы в конечном итоге решение отказаться от письма фронте, незначительная корректировка:

dt[,c("P","F","I","R","C"):= 
    lapply(c("P","F","I","R","C"), 
      function(x)regmatches(code,regexpr(paste0("(?<=",x,")[0-9]+"), 
               code,perl=T)))] 
> dt 
       code P F I R C 
1: P1F2I235R15C145 1 2 235 15 145 
2: P24F1I12R124C96 24 1 12 124 96 

Или используя версию Devel из data.table (v1.9.5+):

dt[, c("P", "F", "I", "R", "C") := 
     tstrsplit(code, "(?<=.)(?=[[:alpha:]][0-9]+)", perl=TRUE)] 
#    code P F I R C 
# 1: P1F2I235R15C145 P1 F2 I235 R15 C145 
# 2: P24F1I12R124C96 P24 F1 I12 R124 C96 
+1

Спасибо @Arun за то, что кажется идеальным решением 'data.table' для этой проблемы, учитывая, что формат' code' является регулярным, имеет смысл использовать 'tstrsplit'; @Arun вы можете придумать легкую настройку, которая разделила бы только цифры, а не буквы ?. – MichaelChirico

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