重塑数据以将列值拆分成列

问题描述 投票:0回答:7
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))
r dplyr reshape
7个回答
7
投票

更新

如果不同类别之间的长度不均匀,我们可以使用

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

6
投票

基地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

6
投票

使用split

data.frame(split(df$hunger, df$animal))
#   cat dog
# 1   1   0
# 2   1   1
# 3   1   0

4
投票

您可以通过首先为每个组创建一个 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


4
投票

整洁的框架方式

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, `+`))

4
投票

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

4
投票

使用

data.table

library(data.table)
dcast(setDT(df), rowid(animal) ~ animal)[, animal  := NULL][]

-输出

    cat dog
1:   1   0
2:   1   1
3:   1   0
© www.soinside.com 2019 - 2024. All rights reserved.