在 r 中将数据帧转换为宽格式?(转置和连接)

convert dataframe to wide format in r ?(transpose and concatenate)

假设

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。 我该怎么做?

你可以使用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")

使用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。