stri_split_fixed в таблице данных в R

У меня есть таблица данных DT следующим образом.

DT <- structure(list(V1 = structure(1:3, .Label = c("S01", "S02", "S03" ), class = "factor"), V2 = structure(c(1L, 3L, 2L), .Label = c("Alan Hal << Guy John", "Bruce Dick Jean-Paul << Damien", "Jay << Barry Wally Bart"), class = "factor")), .Names = c("V1", "V2"), row.names = c(NA, -3L), class = "data.frame")
# DT
#    V1                             V2
# 1 S01           Alan Hal << Guy John
# 2 S02        Jay << Barry Wally Bart
# 3 S03 Bruce Dick Jean-Paul << Damien
setDT(DT)

Я пытаюсь разделить столбец V2 на «‹<» и получить результат в двух новых столбцах.

Я мог бы сделать это следующим образом, используя stringi

T <- as.data.frame(do.call(rbind,  stri_split_fixed(DT$V2, "<<", 2)))
setnames(T, old = colnames(T), new = c("V3", "V4"))
cbind(DT, T)
V1                             V2                    V3                V4
1: S01           Alan Hal << Guy John             Alan Hal           Guy John
2: S02        Jay << Barry Wally Bart                  Jay   Barry Wally Bart
3: S03 Bruce Dick Jean-Paul << Damien Bruce Dick Jean-Paul             Damien

Однако я хотел бы сделать то же самое по ссылке, используя оператор :=. Как это сделать с помощью data.table?

У меня проблемы с правой частью.

DT[, c("V1", "V2) := list()]

stri_split_fixed(DT$V2, "<<", 2) дает список из 3 символьных векторов длины 2. Как получить список из 2 символьных векторов длины 3?


person Crops    schedule 19.01.2015    source источник


Ответы (1)


Вы могли бы попробовать

setDT(DT)[, c('V3', 'V4'):=do.call(rbind.data.frame,
                    stri_split_fixed(V2, ' << ', 2))][]
#  V1                             V2                    V3                V4
#1: S01           Alan Hal << Guy John             Alan Hal           Guy John
#2: S02        Jay << Barry Wally Bart                  Jay   Barry Wally Bart
#3: S03 Bruce Dick Jean-Paul << Damien Bruce Dick Jean-Paul             Damien

Или вы можете использовать strsplit (из комментариев @David Arenburg)

 setDT(DT)[, c('V3', 'V4'):= do.call(rbind.data.frame,
                   strsplit(as.character(V2), " << "))] 

Более эффективный вариант (как предлагает @Ananda Mahto)

cbind(DT, `colnames<-`(stri_split_fixed(DT$V2,
              " << ", simplify = TRUE), c("V3", "V4")))

Другой вариант - использовать cSplit из splitstackshape

library(splitstackshape)
cSplit(DT, 'V2', ' << ', stripWhite=FALSE, drop=FALSE)
#       V1                             V2                 V2_1             V2_2
#1: S01           Alan Hal << Guy John             Alan Hal         Guy John
#2: S02        Jay << Barry Wally Bart                  Jay Barry Wally Bart
#3: S03 Bruce Dick Jean-Paul << Damien Bruce Dick Jean-Paul           Damien

Более быстрая версия cSplit, которая обеспечивает такую ​​же производительность, как и stri_split, доступна в Gist

person akrun    schedule 19.01.2015
comment
Для этого не нужно stringi .. Просто setDT(DT)[, c('V3', 'V4'):= do.call(rbind.data.frame, strsplit(as.character(V2), " << "))] - person David Arenburg; 19.01.2015
comment
@DavidArenburg Я просто копировал код OP. Да, это действительно не нужно. Но, указав fixed, я думаю, что это может быть быстрее - person akrun; 19.01.2015
comment
Мне нравится третий подход :-) ... Хороший синтаксис и достойная производительность. Но первые два варианта меня не впечатляют. Я бы сделал cbind(DT, colnames ‹-_ 2_. Разница должна быть огромной. Кстати, в следующей версии cSplit будет использоваться stri_split_*, поэтому подход cSplit приблизится к этому предложению в комментарии. - person A5C1D2H2I1M1N2O1R2T1; 19.01.2015
comment
@AnandaMahto Я получаю столбец NA и «‹* ‹<« в исходном столбце с использованием cSplit. Очевидно, я не показывал результат :-) Спасибо за другой вариант - person akrun; 19.01.2015
comment
Я думаю, вы хотели использовать stripWhite = FALSE. В моей существующей функции есть проблема с удалением пробелов. - person A5C1D2H2I1M1N2O1R2T1; 19.01.2015
comment
@AnandaMahto Да, это решает проблему. Теперь я могу показать результат :-) - person akrun; 19.01.2015
comment
Черновой Gist из cSplit, который должен дать такую ​​же производительность, как и исходный stri_split подход. - person A5C1D2H2I1M1N2O1R2T1; 19.01.2015