将数据结构从长更改为宽,反之亦然

Change the data structure from long to wide and visa versa

我在使用 reshpe 命令时遇到问题。 我想将数据结构从长更改为宽,反之亦然。 我也尝试了 spreadreshape 以及 dcast。 但是我失败了,我不知道为什么。 这是我的数据和代码

d1<-data.frame(ID=c("id1","id2","id3","id4"), year=c(2000,2001),val=c(8,7,9,8,2,3,5,6))

我想将 ID 变量放置到下面的行中。

  year id1 id2 id3 id4
  2000  8   9   2   5
  2001  7   8   3   6  

我试过了 spread(d1, ID, val)reshape(d1, ID, year,direction="wide")dcast(d1, year~ID, rank) 但是我有错误。

谁能帮帮我? 谢谢。

您定义 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