Pivot/merge 数据集中的一些列,同时保留其余列

Pivot/merge some columns in a dataset while keeping remaining columns

我有一个类似于此的数据集(但有更多列):

table <- "year site square triangle circle
1  2019    A 3 9 5
2  2019    A 5 NA 34
3  2019    B 0 0 69
4  2019    B NA 111 2
5  2020    C 0 45 3
6  2020    C 29 0 NA 
7  2020    D NA 0 1
8  2021    D 3 NA 4
9  2021    D 158 5 0
10 2021    D 2 9 0"

df <- read.table(text=table, header = TRUE)
df

我想旋转 table 的一部分,使其类似于:

   year site type count
1  2019    A square   3
2  2019    A triangle 9
3  2019    A circle   5
4  2019    A square   5
5  2019    A triangle NA
6  2019    A circle   34
7  2019    B square   0
8  2019    B triangle 0 
9  2019    B circle  60

(以此类推)

我尝试过 的解决方案,但这不涉及计数,所以当我使用这些解决方案时我失去了那个值。

例如,下面的代码在每一列中留下了 NA,我丢失了计数值

df2 <- df[1:2]
df2$type <- apply(df[3:5], 1, function(k) names(df[3:5])[k])
df2

   year site             type
1  2019    A   circle, NA, NA
2  2019    A       NA, NA, NA
3  2019    B               NA
4  2019    B NA, NA, triangle
5  2020    C       NA, circle
6  2020    C           NA, NA
7  2020    D       NA, square
8  2021    D   circle, NA, NA
9  2021    D           NA, NA
10 2021    D     triangle, NA

我也试过使用 tidyr gather() 包,但这不允许我保留多列。


library(tidyr)
df3 <- gather(df, year, site, `square`:`circle`)
head(df3)

    year site
1 square    3
2 square    5
3 square    0
4 square   NA
5 square    0
6 square   29

我唯一的想法是在我的数据框中创建一个新的唯一数字列 (1-X),将其与 gather() 一起使用,然后通过该唯一 ID 合并原始数据框和新数据框,然后删除不需要的列。这可行,但我想知道是否有更好、更清洁的解决方案?

怎么样tidyr::pivot_longer:

library(tidyr)

tidyr::pivot_longer(df, -c(year, site))
#> # A tibble: 30 x 4
#>     year site  name     value
#>    <int> <chr> <chr>    <int>
#>  1  2019 A     square       3
#>  2  2019 A     triangle     9
#>  3  2019 A     circle       5
#>  4  2019 A     square       5
#>  5  2019 A     triangle    NA
#>  6  2019 A     circle      34
#>  7  2019 B     square       0
#>  8  2019 B     triangle     0
#>  9  2019 B     circle      69
#> 10  2019 B     square      NA
#> # … with 20 more rows