在 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。
假设
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。