2012-03-25 2 views
3

У меня есть текстовая переменная и переменная группировки. Я хотел бы свернуть текстовую переменную в одну строку за строку (объединить). Поэтому, пока колонка группы говорит m Я хочу сгруппировать текст вместе и так далее. Я представил образец данных до и после. Я пишу это для пакета и до сих пор избегал всякой зависимости от других пакетов, кроме wordcloud, и хотел бы сохранить его таким образом.Свернуть столбики путем группировки переменной (в базе)

Я подозреваю, что rle может быть полезен с cumsum, но не смог вычислить этот вариант.

Заранее спасибо.

Что данные выглядят как

        text group 
1  Computer is fun. Not too fun.  m 
2    No its not, its dumb.  m 
3    How can we be certain?  f 
4     There is no way.  m 
5      I distrust you.  m 
6   What are you talking about?  f 
7  Shall we move on? Good then.  f 
8 Im hungry. Lets eat. You already?  m 

То, что я хотел бы данные, чтобы выглядеть

             text group 
1  Computer is fun. Not too fun. No its not, its dumb.  m 
2         How can we be certain?  f 
3       There is no way. I distrust you.  m 
4 What are you talking about? Shall we move on? Good then.  f 
5      Im hungry. Lets eat. You already?  m 

В данных

dat <- structure(list(text = c("Computer is fun. Not too fun.", "No its not, its dumb.", 
"How can we be certain?", "There is no way.", "I distrust you.", 
"What are you talking about?", "Shall we move on? Good then.", 
"Im hungry. Lets eat. You already?"), group = structure(c(2L, 
2L, 1L, 2L, 2L, 1L, 1L, 2L), .Label = c("f", "m"), class = "factor")), .Names = c("text", 
"group"), row.names = c(NA, 8L), class = "data.frame") 

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

x <- rle(as.character(dat$group))[[1]] 
dat$new <- as.factor(rep(1:length(x), x)) 

Уступая:

        text group new 
1  Computer is fun. Not too fun.  m 1 
2    No its not, its dumb.  m 1 
3    How can we be certain?  f 2 
4     There is no way.  m 3 
5      I distrust you.  m 3 
6   What are you talking about?  f 4 
7  Shall we move on? Good then.  f 4 
8 Im hungry. Lets eat. You already?  m 5 

ответ

5

Это делает использование RLE, чтобы создать идентификатор, чтобы сгруппировать предложения на. Он использует tapply вместе с пастой, чтобы довести выход вместе

## Your example data 
dat <- structure(list(text = c("Computer is fun. Not too fun.", "No its not, its dumb.", 
"How can we be certain?", "There is no way.", "I distrust you.", 
"What are you talking about?", "Shall we move on?  Good then.", 
"Im hungry.  Lets eat.  You already?"), group = structure(c(2L, 
2L, 1L, 2L, 2L, 1L, 1L, 2L), .Label = c("f", "m"), class = "factor")), .Names = c("text", 
"group"), row.names = c(NA, 8L), class = "data.frame") 


# Needed for later 
k <- rle(as.numeric(dat$group)) 
# Create a grouping vector 
id <- rep(seq_along(k$len), k$len) 
# Combine the text in the desired manner 
out <- tapply(dat$text, id, paste, collapse = " ") 
# Bring it together into a data frame 
answer <- data.frame(text = out, group = levels(dat$group)[k$val]) 
+1

Я не верю, что вам нужно «Seq (длина (k $ len)) », так как последовательность будет« seq_along »вектором длины k $, давая вам эквивалентную последовательность чисел: id <- rep (seq (k $ length), k $ length) –

+0

@BryanGoodrich Хорошая уловка , Первоначально я просто собирался сделать 1: length (k $ len), но в последнее время я больше двигаюсь к использованию seq и seq_along, и, я думаю, у меня получилось несоответствие двух подходов. – Dason

+0

Обычно я просто придерживаюсь seq, но для ясности я вижу, как seq_along делает это явным, что вы численно пересекаете вектор значений. Я часто склоняюсь к этому пути ясности, когда имею дело с избыточным булевым вектором, используя x [который (... какая-то логика здесь ...)]. Это не обязательно, но это дает лингвистическую ясность для кодирования, которое я предпочитаю. –

1

я получил ответ и вернулся к сообщению, но Dason бить меня к нему и более понятным, чем мои собственные.

x <- rle(as.character(dat$group))[[1]] 
dat$new <- as.factor(rep(1:length(x), x)) 

Paste <- function(x) paste(x, collapse=" ") 
aggregate(text~new, dat, Paste) 

EDIT Как я хотел бы сделать это с агрегировать и то, что я узнал от вашего ответа (хотя tapply является лучшим решением):

y <- rle(as.character(dat$group)) 
x <- y[[1]] 
dat$new <- as.factor(rep(1:length(x), x)) 

text <- aggregate(text~new, dat, paste, collapse = " ")[, 2] 
data.frame(text, group = y[[2]]) 
+1

Обратите внимание, что вам не нужно определять «Вставить», поскольку агрегат позволяет передавать дополнительные параметры к применяемой функции. Вы должны уметь удалять Paste и использовать это вместо 'aggregate (text ~ new, dat, paste, collapse =" ")' – Dason

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