Разделить строку на несколько строк заглавными буквами с помощью cSplit

У меня есть данные опроса. Некоторые вопросы допускали несколько ответов. В моих данных разные ответы разделены запятой. Я хочу добавить новую строку в кадр данных для каждого выбора. Итак, у меня есть что-то вроде этого:

survey$q1 <- c("I like this", "I like that", "I like this, but not much",
 "I like that, but not much", "I like this,I like that", 
"I like this, but not much,I like that")

Если бы запятые были только там, чтобы разделить несколько вариантов, которые я бы использовал:

survey <- cSplit(survey, "q1", ",", direction = "long")

и получить желаемый результат. Учитывая, что некоторые запятые являются частью ответа, я попытался использовать запятую, за которой следует заглавная буква, в качестве разделителя:

survey <- cSplit(survey, "q1", ",(?=[A-Z])", direction = "long")

Но почему-то не работает. Это не дает никаких ошибок, но не разбивает строки, а также удаляет некоторые строки из фрейма данных. Затем я попытался использовать strsplit:

strsplit(survey$1, ",(?=[A-Z])", perl=T)

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

survey$q1
[1] "I like this"
[2] "I like that"
[3] "I like this, but not much"
[4] "I like that, but not much"
[5] "I like this"
[6] "I like that"
[7] "I like this, but not much"
[8] "I like that"

Есть ли способ получить его одним из двух способов? Спасибо


person Antonio    schedule 06.09.2019    source источник


Ответы (2)


Вариант с separate_rows

library(dplyr)
library(tidyr)
survey %>% 
   separate_rows(q1, sep=",(?=[A-Z])")
#                       q1
#1               I like this
#2               I like that
#3 I like this, but not much
#4 I like that, but not much
#5               I like this
#6               I like that
#7 I like this, but not much
#8               I like that

С cSplit есть аргумент fixed, который по умолчанию равен TRUE, но если мы используем fixed = FALSE, это может привести к сбою. Может быть, потому что он не оптимизирован для выражений регулярных выражений PCRE.

library(splitstackshape)
cSplit(survey, "q1", ",(?=[A-Z])", direction = "long", fixed = FALSE)

Ошибка в strsplit(indt[[splitCols[x]]], split = sep[x], fixed = fixed): недопустимое регулярное выражение ',(?=[A-Z])', причина 'Недопустимое регулярное выражение'

Один из вариантов обойти это — изменить столбец с помощью функции (sub/gsub), которая может использовать регулярное выражение PCRE для изменения sep, а затем использовать cSplit для этого sep.

cSplit(transform(survey, q1 = sub(",(?=[A-Z])", ":", q1, perl = TRUE)), 
         "q1", sep=":", direction = "long")
#                        q1
#1:               I like this
#2:               I like that
#3: I like this, but not much
#4: I like that, but not much
#5:               I like this
#6:               I like that
#7: I like this, but not much
#8:               I like that

данные

survey <- structure(list(q1 = c("I like this", "I like that", "I like this, but not much", 
"I like that, but not much", "I like this,I like that", "I like this, but not much,I like that"
)), class = "data.frame", row.names = c(NA, -6L))
person akrun    schedule 06.09.2019
comment
Спасибо. Я пытался, но получил эту ошибку, я не знаю, почему это не работает с символами: Ошибка в UseMethod (separate_rows_): нет применимого метода для «separate_rows_», примененного к объекту символа класса - person Antonio; 06.09.2019
comment
@Antonio Можете ли вы примерить data, который я показал в своем посте? - person akrun; 06.09.2019
comment
Я сделал, я действительно получаю ту же ошибку. Кроме того, я должен использовать Survey$q1 как x, а не просто q1. - person Antonio; 06.09.2019
comment
Пробовал проверять часть cSplit, вы правы, именно так и происходит - person Antonio; 06.09.2019
comment
@Антонио. separate_rows принимает имя data.frame и столбца как «q1». Но если вы используете survey$q1, я не вижу смысла использовать cSplit - person akrun; 06.09.2019
comment
@Antonio Антонио, я обновил dd с помощью cSplit, теперь должно работать - person akrun; 06.09.2019
comment
@ Антонио Что касается вашего комментария Plus I have to use survey$q1 as x, rather than just q1, да. не тот случай, когда вы использовали cSplit - person akrun; 06.09.2019
comment
Спасибо! он работает почти идеально, есть еще пара ответов, которые он не определяет, но я поиграюсь с ним, пока он не обнаружит! - person Antonio; 06.09.2019
comment
что касается Плюса, я должен использовать Survey$q1 как x, а не просто q1, я имел в виду, что получил ошибку, используя ваше исходное решение с разделением_рядов - person Antonio; 06.09.2019
comment
@Антонио. Хорошо, тогда я не понимаю, почему вы используете cSplit вместо strsplit - person akrun; 06.09.2019
comment
@Антонио separate_rows из tidyr. Я использую версию tidyr для разработчиков, хотя она должна работать, если ваша версия является последней последней версией CRAN. - person akrun; 06.09.2019
comment
потому что у меня есть другие столбцы с идентификатором, например, и мне нужно, чтобы переменная идентификатора имела одинаковое значение для двух частей строки, которые теперь являются двумя разными строками. - person Antonio; 06.09.2019
comment
Ок, проверю версию. Спасибо большое - person Antonio; 06.09.2019
comment
на самом деле к вашему коду добавить было нечего, у меня были строки, которые нужно было разбить на 3 части, и простое выполнение одной и той же команды дважды помогло. Я не понимаю, почему, но это нормально - person Antonio; 06.09.2019

Ответ @akrun правильный. Я просто хотел добавить, что если вам нужно разделить некоторые строки более чем на 2 части, способ работы его кода — просто запустить одну и ту же строку несколько раз. Я не совсем уверен, почему это так, но это работает

person Antonio    schedule 06.09.2019