您定义d1 的方式存在问题。具体来说,您已将其内容定义为三个不同长度的向量。原则上这是可以的,因为data.frame 将有效地回收向量以强制它们相等长度。问题是完成这种回收的方式与您最终想要获得的宽幅格式不一致。我们可以通过使用pivot_wider() 来证明这一点——tidyr 包中最近添加的内容之一:
d1 <-
data.frame(
ID = c("id1", "id2", "id3", "id4"),
year = c(2000, 2001),
val = c(8, 7, 9, 8, 2, 3, 5, 6)
)
tidyr::pivot_wider(d1, names_from = ID, values_from = val)
#> Warning: Values in `val` are not uniquely identified; output will contain list-cols.
#> * Use `values_fn = list(val = list)` to suppress this warning.
#> * Use `values_fn = list(val = length)` to identify where the duplicates arise
#> * Use `values_fn = list(val = summary_fun)` to summarise duplicates
#> # A tibble: 2 x 5
#> year id1 id2 id3 id4
#> <dbl> <list> <list> <list> <list>
#> 1 2000 <dbl [2]> <NULL> <dbl [2]> <NULL>
#> 2 2001 <NULL> <dbl [2]> <NULL> <dbl [2]>
请注意,虽然该命令没有产生错误,但产生的结果肯定与您预期的不相符。幸运的是,解决这个问题就像正确定义输入数据框的列一样简单。下面,我为d2 完成了该操作,并显示了pivot_wider() 产生的结果。我相信这符合您的预期?
d2 <- data.frame(
ID = c("id1", "id1", "id2", "id2", "id3", "id3", "id4", "id4"),
year = c(2000, 2001, 2000, 2001, 2000, 2001, 2000, 2001),
val = c(8, 7, 9, 8, 2, 3, 5, 6)
)
tidyr::pivot_wider(d2, names_from = ID, values_from = val)
#> # A tibble: 2 x 5
#> year id1 id2 id3 id4
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 2000 8 9 2 5
#> 2 2001 7 8 3 6
另外,如果您使用d2 作为输入,您的展开命令应该会产生与pivot_wider() 相同的结果:
tidyr::spread(d2, ID, val)
#> year id1 id2 id3 id4
#> 1 2000 8 9 2 5
#> 2 2001 7 8 3 6