我有一个非常不整洁的数据集
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 Messenger数据,这就是您下载它时使用的表格。
谢谢。
答案 0 :(得分:2)
在这种情况下,您的起始数据集只有一列(又称功能)。但是在这种情况下,每种消息在此处编码的数据类型有三种:时间戳记,人员标签和消息。将它们转换成表格,其中每个消息都在其自己的行中,并且每一列代表每个观察值的不同方面,即长或整洁的格式:https://cran.r-project.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
答案 1 :(得分:1)
另一种选择是只使用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))
答案 2 :(得分:0)
这是一种方法:
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
这将为每条消息编号,并将数据放入列列表中。