Разделение строки в R, разные элементы аргумента разделения

Я импортировал некоторые данные без имен столбцов, так что теперь у меня чуть больше миллиона строк и 1 столбец (вместо 5 столбцов).

Каждая строка форматируется следующим образом:

x <- "2012-10-19T16:59:01-07:00 192.101.136.140 <190>Oct 19 2012 23:59:01: %FWSM-6-305011: Built dynamic tcp translation from Inside:10.2.45.62/56455 to outside:192.101.136.224/9874"

strsplit( x , split = c(" ", " ", "%", " "))

и получил

[[1]]
 [1] "2012-10-19T16:59:01-07:00"    "192.101.136.140"             
 [3] "<190>Oct"                     "19"                          
 [5] "2012"                         "23:59:01:"                   
 [7] "%FWSM-6-305011:"              "Built"                       
 [9] "dynamic"                      "tcp"                         
[11] "translation"                  "from"                        
[13] "Inside:10.2.45.62/56455"      "to"                          
[15] "outside:192.101.136.224/9874"

Я знаю, что это связано с повторным использованием аргумента разделения, но я не могу понять, как получить его так, как я хочу:

    [[1]]
     [1] "2012-10-19T16:59:01-07:00"    "192.101.136.140"             
     [3] "<190>Oct 19 2012 23:59:01     "%FWSM-6-305011
     [5] Built dynamic tcp translation from Inside:10.2.45.62/56455 to outside:192.101.136.224/9874"

Каждая строка имеет другое сообщение в качестве пятого элемента, но после 4-го элемента я просто хочу сохранить остальную часть строки вместе.

Любая помощь будет оценена по достоинству.


person camelarms    schedule 25.07.2013    source источник
comment
Кажется, вы думаете (ошибочно), что элементы разделенного вектора применяются последовательно.   -  person IRTFM    schedule 26.07.2013
comment
Это верно. Спасибо за прояснение   -  person camelarms    schedule 26.07.2013


Ответы (3)


Вы можете использовать paste с аргументом collapse для объединения всех элементов, начиная с пятого элемента.

A <- strsplit( x = "2012-10-19T16:59:01-07:00 192.101.136.140 <190>Oct 19 2012 23:59:01: %FWSM-6-305011: Built dynamic tcp translation from Inside:10.2.45.62/56455 to outside:192.101.136.224/9874", split = c(" ", " ", "%", " "))

c(A[[1]][1:4], paste(A[[1]][5:length(A[[1]])], collapse=" "))

Как указывает @DWin, split = c(" ", " ", "%", " ") не используется по порядку - другими словами, он идентичен split = c(" ", "%")

person Señor O    schedule 25.07.2013
comment
Спасибо @Senor O, это почти помогло. Последняя часть вышла как "[3] "<190>Oct" [4] "19" [5] "2012 23:59:01: %FWSM-6-305011: Built dynamic tcp translation from Inside:10.2.45.62/56455 to outside:192.101.136.224/9874" - person camelarms; 26.07.2013
comment
Это потому, что первые 7 элементов вашей разделенной строки предшествуют сообщению (в отличие от того, что вы изначально сказали с 4). - person Señor O; 26.07.2013
comment
Имейте в виду, что <190>Oct 19 2012 23:59:01: будет разделен на 4 элемента. - person Señor O; 26.07.2013
comment
Ах, извините, не увидел последнюю часть вашего ответа - person camelarms; 26.07.2013

Я думаю, что здесь вам не нужно использовать strsplit. Я использую read.table для чтения строк, используя аргумент text. Затем вы агрегируете столбцы, используя paste. Поскольку у вас много строк, лучше выполнять агрегацию столбцов в data.table.

dt <- read.table(text=x)
library(data.table)
DT <- as.data.table(dt)
DT[ , c('V3','V8') := list(paste(V3,V4,V5),
      V8=paste(V8,V9,V10,V11,V12,V13,V14,V15))]
DT[,paste0('V',c(1:3,6:7,8)),with=FALSE]

                        V1              V2               V3        V6              V7
1: 2012-10-19T16:59:01-07:00 192.101.136.140 <190>Oct 19 2012 23:59:01: %FWSM-6-305011:
                                                                                           V8
1: Built dynamic tcp translation from Inside:10.2.45.62/56455 to outside:192.101.136.224/9874
person agstudy    schedule 25.07.2013

Вот функция, которая, я думаю, работает так, как вы думали, что strsplit функционировала:

split.seq<-function(x,delimiters) {
  break.point<-regexpr(delimiters[1], x)
  first<-mapply(substring,x,1,break.point-1,USE.NAMES=FALSE)
  second<-mapply(substring,x,break.point+1,nchar(x),USE.NAMES=FALSE)
  if (length(delimiters)==1)  return(lapply(1:length(first),function(x) c(first[x],second[x])))
  else mapply(function(x,y) c(x,y),first, split.seq(second, delimiters[-1]) ,USE.NAMES=FALSE, SIMPLIFY=FALSE)
}

split.seq(x,delimiters)

Тест:

x<-rep(x,2)             
delimiters=c(" ", " ", "%", " ")
split.seq(x,delimiters)

[[1]]
[1] "2012-10-19T16:59:01-07:00"                                                                 
[2] "192.101.136.140"                                                                           
[3] "<190>Oct 19 2012 23:59:01: "                                                               
[4] "FWSM-6-305011:"                                                                            
[5] "Built dynamic tcp translation from Inside:10.2.45.62/56455 to outside:192.101.136.224/9874"

[[2]]
[1] "2012-10-19T16:59:01-07:00"                                                                 
[2] "192.101.136.140"                                                                           
[3] "<190>Oct 19 2012 23:59:01: "                                                               
[4] "FWSM-6-305011:"                                                                            
[5] "Built dynamic tcp translation from Inside:10.2.45.62/56455 to outside:192.101.136.224/9874"
person nograpes    schedule 26.07.2013