通过 R 中的变量将行重塑为列表

Reshaping rows to lists by variable in R

我有一个如下所示的数据框:

  class id
1   foo  1
2   bar  1
3   baz  1
4   baz  2
5   bar  2
6   foo  2
7   foo  3
8   foo  3
9   foo  3

我的目标是将其重塑为一个数据框,按照给定的顺序将 类 收集到一个列表中。例如,输出如下所示:

> output
  id var1 var2 var3
1  1  foo  bar  baz
2  2  baz  bar  foo
3  3  foo  foo  foo

或者,一个双列数据框,第一列包含 id,第二列按顺序包含 id 变量列表。

我已经尝试使用重塑库中的 dcast(test, id ~ class),但这并不完全 return 我需要的输出。

关于如何在 R 中执行此操作的任何想法?这是数据:

dput(test)
structure(list(class = c("foo", "bar", "baz", "baz", "bar", "foo", 
"foo", "foo", "foo"), id = c(1, 1, 1, 2, 2, 2, 3, 3, 3)), row.names = c(NA, 
-9L), class = "data.frame")

我们通过'id'创建一个序列列,然后使用spread

library(tidyverse)
test %>% 
     group_by(id) %>% 
     mutate(rn = str_c("var", row_number())) %>% 
      spread(rn, class)
# A tibble: 3 x 4
# Groups:   id [3]
#     id var1  var2  var3 
#  <dbl> <chr> <chr> <chr>
#1     1 foo   bar   baz  
#2     2 baz   bar   foo  
#3     3 foo   foo   foo  

以防万一

test %>%
     group_by(id) %>%
     mutate(rn = paste0("var", row_number())) %>%
     spread(rn, class)

test %>%
    group_by(id) %>%
    mutate(rn = paste("var", row_number(), sep="")) %>%
    spread(rn, class)

或使用 data.table,使用 rowiddcast

创建序列
library(data.table)
dcast(setDT(test), id ~ paste0("var", rowid(id)), value.var = 'class')
#    id var1 var2 var3
#1:  1  foo  bar  baz
#2:  2  baz  bar  foo
#3:  3  foo  foo  foo

如果我们想使用 base R,一个选项是 avereshape

reshape(transform(test, rn = paste0("var", ave(seq_along(id), id,
   FUN = seq_along))), idvar = 'id', direction = 'wide', timevar = 'rn')

注意:当重复次数不相等时,所有方法都有效

您可以通过 idcbind 有趣的列来 split 数据框。

data.frame(id=unique(d$id), t(do.call(cbind, split(d$class, d$id))))
#   id  X1  X2  X3
# 1  1 foo bar baz
# 2  2 baz bar foo
# 3  3 foo foo foo

注意: 使用 cbind.data.frame 你不需要因子的情况。

数据

d <- structure(list(class = c("foo", "bar", "baz", "baz", "bar", "foo", 
"foo", "foo", "foo"), id = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 
3L)), row.names = c(NA, -9L), class = "data.frame")