通过 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
,使用 rowid
和 dcast
创建序列
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
,一个选项是 ave
和 reshape
reshape(transform(test, rn = paste0("var", ave(seq_along(id), id,
FUN = seq_along))), idvar = 'id', direction = 'wide', timevar = 'rn')
注意:当重复次数不相等时,所有方法都有效
您可以通过 id
和 cbind
有趣的列来 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")
我有一个如下所示的数据框:
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
,使用 rowid
和 dcast
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
,一个选项是 ave
和 reshape
reshape(transform(test, rn = paste0("var", ave(seq_along(id), id,
FUN = seq_along))), idvar = 'id', direction = 'wide', timevar = 'rn')
注意:当重复次数不相等时,所有方法都有效
您可以通过 id
和 cbind
有趣的列来 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")