df <- data.frame(animal = c("dog", "dog", "cat", "dog", "cat", "cat"),
hunger = c(0, 1, 1, 0, 1,1))
我有一个像上面的数据框,有两列,一列包含类别,另一列包含二进制数据。
我希望重塑数据框以将类别(“动物”)列拆分为自己的两列,其中“动物”列的值作为列名,另一列(饥饿)的值作为单元格值,即
期望的输出:
df <- data.frame(dog = c(0, 1, 0),
cat = c(1, 1, 1))
如果不同类别之间的长度不均匀,我们可以使用
list2DF(
lapply(
. <- unstack(rev(df)),
`length<-`,
max(lengths(.))
)
)
list2DF(
lapply(
. <- unstack(df, hunger ~ animal),
`length<-`,
max(lengths(.))
)
)
或
list2DF(
lapply(
. <- unstack(rev(df)),
`length<-`,
max(lengths(.))
)
)
我们将获得
cat dog
1 1 0
2 1 1
3 1 0
4 0 NA
虚拟数据
df <- data.frame(
animal = c("dog", "dog", "cat", "dog", "cat", "cat", "cat"),
hunger = c(0, 1, 1, 0, 1, 1, 0)
)
我们可以使用
unstack
,例如,
> unstack(rev(df))
cat dog
1 1 0
2 1 1
3 1 0
或
> unstack(df, hunger ~ animal)
cat dog
1 1 0
2 1 1
3 1 0
基地R:
df$id <- ave(df$hunger, df$animal, FUN = seq_along)
reshape(df, idvar = "id", timevar = "animal", direction = "wide")[, -1]
hunger.dog hunger.cat
1 0 1
2 1 1
4 0 1
使用split:
data.frame(split(df$hunger, df$animal))
# cat dog
# 1 1 0
# 2 1 1
# 3 1 0
您可以通过首先为每个组创建一个 id 来识别重复项并使用
pivot_wider
和 names_from
来使用 values_from
,如下所示:
library(dplyr)
library(tidyr)
df %>%
group_by(animal) %>%
mutate(id = row_number()) %>%
pivot_wider(names_from = animal, values_from = hunger) %>%
select(-id)
#> # A tibble: 3 × 2
#> dog cat
#> <dbl> <dbl>
#> 1 0 1
#> 2 1 1
#> 3 0 1
创建于 2023-03-17 与 reprex v2.0.2
整洁的框架方式
library(dplyr)
library(tidyr)
df |>
pivot_wider(names_from = animal, values_from = hunger, values_fn = list) |>
unnest(cols = c("dog", "cat"))
基础R
do.call(cbind.data.frame, tapply(df$hunger, df$animal, `+`))
将
tidyverse/purrr
溶液加入混合物中:
library(tidyverse)
df <- data.frame(animal = c("dog", "dog", "cat", "dog", "cat", "cat"),
hunger = c(0, 1, 1, 0, 1,1))
df %>%
group_split(animal) %>%
map(~tibble(!!quo_name(unique(.x$animal)) := .x$hunger)) %>%
list_cbind()
#> # A tibble: 3 × 2
#> cat dog
#> <dbl> <dbl>
#> 1 1 0
#> 2 1 1
#> 3 1 0
使用
data.table
library(data.table)
dcast(setDT(df), rowid(animal) ~ animal)[, animal := NULL][]
-输出
cat dog
1: 1 0
2: 1 1
3: 1 0