让我们说
df:
user actions
1 A
1 B
1 c
2 A
2 D
3 B
4 C
4 D
我想转换为这种格式
new_df:
user action1 action2 action3
1 A B C
2 A D NA
3 B NA NA
4 C D NA
请注意new_df
中的列数等于用户之间的最大操作数。如果用户少于最大动作,则应插入NA。
我该怎么做?
答案 0 :(得分:2)
您可以使用rle
创建一个列来存储action1,action2等。然后使用data.table包中的dcast
将数据转换为宽格式。
df$coln <- paste0("actions", unlist(lapply(rle(df$user)$lengths, seq_len)))
data.table::dcast(df, user ~ coln, value.var="actions")
在回应OP的评论时,你可以用0填写开头,如下所示:
df$coln <- paste0("actions", sprintf("%02d", unlist(lapply(rle(df$user)$lengths, seq_len))))
使用data.table
包:
df <- read.table(text="user actions
1 A
1 B
1 C
1 D
1 E
1 F
1 G
1 H
1 I
1 J
1 K
2 A
2 D
3 B
4 C
4 D", header=TRUE)
library(data.table)
setDT(df)
dcast(setDT(df)[, coln := sprintf("actions%02d", seq_len(.N)), by=.(user)],
user ~ coln, value.var="actions")
答案 1 :(得分:1)
使用tidyverse
方法的解决方案
df <- read.table(text = "user actions
1 A
1 B
1 c
2 A
2 D
3 B
4 C
4 D", header = TRUE)
library(tidyr)
library(dplyr)
df %>%
group_by(user) %>%
mutate(index = paste0("action", row_number())) %>%
spread(index, actions)
#> # A tibble: 4 x 4
#> # Groups: user [4]
#> user action1 action2 action3
#> <int> <fct> <fct> <fct>
#> 1 1 A B c
#> 2 2 A D <NA>
#> 3 3 B <NA> <NA>
#> 4 4 C D <NA>
由reprex package(v0.2.0)创建于2018-04-11。