按组将列转换为多列

时间:2015-03-15 15:14:49

标签: r

我有一个数据框(df):

group col
a     12
a     15
a     13
b     21
b     23

所需的输出也是数据帧(df1):

col1  col2
12    21
15    23
13    0

Namley,我想将“df”中的“df”按“group”划分为多列“col1”和“col2”。

当每列的长度彼此不相等时,必须在每列的末尾添加“0”,直到每列的长度达到最大列长度。

3 个答案:

答案 0 :(得分:4)

我们可以使用base R函数splitunstack将'col'拆分为'group'到列表中,然后填充NA列出要素小于list元素的最大长度。更改列名称,将“NA”替换为0.

  lst <- unstack(df1, col~group)
  d1 <- as.data.frame(sapply(lst, `length<-`, max(sapply(lst, length))))
  d1[is.na(d1)] <- 0
  colnames(d1) <- paste0('col', 1:ncol(d1))
  d1
 #  col1 col2
 #1   12   21
 #2   15   23
 #3   13    0

或使用stri_list2matrix

中的stringi
library(stringi)
d1 <- as.data.frame(stri_list2matrix(unstack(df1, col~group),
            fill=0), stringsAsFactors=FALSE)
d1[] <- lapply(d1, as.numeric)

或使用data.table/splitstackshape

library(splitstackshape)
setnames(dcast(getanID(df1, 'group'), .id~group, value.var='col',
             fill=0L)[, .id:= NULL], paste0('col', 1:2))[]
#    col1 col2
#1:   12   21
#2:   15   23
#3:   13    0

答案 1 :(得分:4)

如何使用dplyr ...

library(dplyr)
library(tidyr)

df1 %>%
  group_by(group) %>%
  mutate(n = row_number()) %>%
  spread(group, col) %>%
  select(-n) %>%
  (function(x) { x[is.na(x)] <- 0; x })

答案 2 :(得分:3)

因为你用零填充,另一个想法是:

xtabs(col ~ ave(DF$col, DF$group, FUN = seq_along) + group, DF)
#                                      group
#ave(DF$col, DF$group, FUN = seq_along)  a  b
#                                     1 12 21
#                                     2 15 23
#                                     3 13  0

“DF”:

DF = structure(list(group = structure(c(1L, 1L, 1L, 2L, 2L), .Label = c("a", 
"b"), class = "factor"), col = c(12L, 15L, 13L, 21L, 23L)), .Names = c("group", 
"col"), class = "data.frame", row.names = c(NA, -5L))