Распределение данных - данные распределены по трем строкам - dplyr - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть очень неопрятный набор данных, похожий на этот

A tibble: 200000 x 2
ChatData  
 <chr>                  
 1 Sep 30, 2018 7:12pm       
 2 Person A
 3 Hello                        
 4 Sep 30, 2018 7:11pm        
 5 Person B           
 6 Hello there                 
 7 Sep 30, 2018 7:10pm        
 8 Person A
...

Как вы видите, идут дата, имя человека, комментарий и повторы.

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

Я хотел бы преобразовать это в нечто вроде

Person A , Person B
Hello      NA
NA         Hello there
how's you, NA
...

(Дата в виде имени строки или третьего столбца была бы отличной, но не существенной для вопроса)

Оптимально я ищу решение dplyr / tidyverse. Я работаю с большим количеством данных, поэтому не медлительно для циклов и т. Д...

Необработанные данные для работы:

structure(list(ChatData = c("Sep 30, 2018 7:12pm", "Person A", "Hello", "Sep 30, 2018 7:11pm", "Person B", "Hello there")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

Если кому-то интересно, я анализирую данные мессенджера Facebook, и это форма, которую вы получаете при загрузке.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

В этом случае ваш начальный набор данных имеет только один столбец (особенность).Но в этом случае есть три типа данных, которые закодированы здесь о каждом сообщении: временная метка, метка человека и сообщение.Было бы более полезно преобразовать их в таблицу, в которой каждое сообщение находится в отдельной строке, и каждый столбец представляет отдельный аспект каждого наблюдения, то есть в длинном или «аккуратном» формате: https://cran.r -проект.org / web / packages / tidyr / vignettes / tidy-data.html

В приведенном ниже подходе пользователь сначала определяет, какие функции повторяются в наборе данных.Я называю их «заголовками» здесь, так как я работаю над таблицей, где это заголовки столбцов.Затем сценарий добавляет эту информацию к данным и преобразует данные из одного столбца в аккуратный формат с одной строкой на сообщение и одним аспектом каждого сообщения в каждом столбце.

Запрошенные выходные данные представляют собой незначительное изменениеэто указано в последней строке ниже: %>% spread(person, msg), которая разделяет данные Person A и Person b на отдельные столбцы.

library(tidyverse)

header_names <- c("timestamp", "person", "msg")

rows_per <- length(header_names)
data_length <- length(data$ChatData) / rows_per
data2 <- data %>%
  mutate(msg_number = rep(1:(nrow(data)/rows_per), each=rows_per),
         # This line repeats the header_names sequence for each msg
         header = rep(header_names, data_length)) %>%
  spread(header, ChatData) %>%
  mutate(timestamp = lubridate::mdy_hm(timestamp)) %>%
  spread(person, msg)


head(data2)
# A tibble: 2 x 4
  msg_number timestamp           `Person A` `Person B` 
       <int> <dttm>              <chr>      <chr>      
1          1 2018-09-30 19:12:00 Hello      NA         
2          2 2018-09-30 19:11:00 NA         Hello there
0 голосов
/ 20 сентября 2018

Поскольку у вас в основном просто символьный вектор, который вы хотели бы преобразовать в 3 столбца data.frame

Еще один вариант - просто использовать matrix и указать ncol=3 и byrow=TRUE

# your sample data
d <- structure(list(ChatData = c("Sep 30, 2018 7:12pm", "Person A", "Hello", "Sep 30, 2018 7:11pm", "Person B", "Hello there")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

matrix( d$ChatData, ncol=3, byrow=TRUE,
        dimnames=list( NULL, c("date_time", "person", "message")) )

Результатом является символьная матрица:

     date_time             person     message      
[1,] "Sep 30, 2018 7:12pm" "Person A" "Hello"      
[2,] "Sep 30, 2018 7:11pm" "Person B" "Hello there"

Но вы можете обернуть это в as.data.frame() для преобразования в data.frame и продолжить работу с dplyr, если этото, что вы хотите.

Соберите все вместе для целого решения:

Это становится хорошим коротким, читаемым битом кода IMO:

library(dplyr)
library(lubridate)

result_df <- 
  matrix( d$ChatData, ncol=3, byrow=TRUE, 
          dimnames=list(NULL, c("date_time", "person", "message")) ) %>% 
  as.data.frame() %>% 
  mutate(date_time=lubridate::mdy_hm(date_time))
0 голосов
/ 19 сентября 2018

Вот один из подходов:

data %>% group_by(msg_number = rep(1:(nrow(data)/3), each=3)) %>% 
  summarize(msg_data = list(ChatData)) %>% as.data.frame

  msg_number                                   msg_data
1          1       Sep 30, 2018 7:12pm, Person A, Hello
2          2 Sep 30, 2018 7:11pm, Person B, Hello there

Это нумерует каждое сообщение и помещает данные в список столбцов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...