将数据结构从长更改为宽,反之亦然
Change the data structure from long to wide and visa versa
我在使用 reshpe 命令时遇到问题。
我想将数据结构从长更改为宽,反之亦然。
我也尝试了 spread
和 reshape
以及 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
我在使用 reshpe 命令时遇到问题。
我想将数据结构从长更改为宽,反之亦然。
我也尝试了 spread
和 reshape
以及 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