具有多列的 R 中的 pivot_wider,但将先前变量的名称保留在单独的列中

时间:2021-01-13 15:27:20

标签: r tidyr

假设我希望通过不同的 setosa-ID 以宽格式放置数据。

iris2 <- iris %>%
          head(10) %>%
          mutate(num = 1:10,
          ID = str_c(Species,1:10))

       Sepal.Length Sepal.Width Petal.Length Petal.Width Species num       ID
1           5.1         3.5          1.4         0.2     setosa   1  setosa1
2           4.9         3.0          1.4         0.2     setosa   2  setosa2
3           4.7         3.2          1.3         0.2     setosa   3  setosa3
4           4.6         3.1          1.5         0.2     setosa   4  setosa4
5           5.0         3.6          1.4         0.2     setosa   5  setosa5
6           5.4         3.9          1.7         0.4     setosa   6  setosa6
7           4.6         3.4          1.4         0.3     setosa   7  setosa7
8           5.0         3.4          1.5         0.2     setosa   8  setosa8
9           4.4         2.9          1.4         0.2     setosa   9  setosa9
10          4.9         3.1          1.5         0.1     setosa  10  setosa10

然而,pivot_wider 为结果返回某种对角矩阵

iris3 <- iris2 %>%
  pivot_wider(names_from = ID,
              values_from = c(Sepal.Length,Sepal.Width,Petal.Length,Petal.Width))

   Species   num Sepal.Length_se~ Sepal.Length_se~ Sepal.Length_se~ Sepal.Length_se~ Sepal.Length_se~ Sepal.Length_se~
   <fct>   <int>            <dbl>            <dbl>            <dbl>            <dbl>            <dbl>            <dbl>
 1 setosa      1              5.1             NA               NA               NA                 NA             NA  
 2 setosa      2             NA                4.9             NA               NA                 NA             NA  
 3 setosa      3             NA               NA                4.7             NA                 NA             NA  
 4 setosa      4             NA               NA               NA                4.6               NA             NA  
 5 setosa      5             NA               NA               NA               NA                  5             NA  
 6 setosa      6             NA               NA               NA               NA                 NA              5.4

我希望数据变成这样:

iris_want <- tibble("Species" = rep("setosa",40),
                    "num" = rep(1:10,each=4),
                    "Values_From" = rep(c("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width"),10),
                    "setosa1" = NA,
                    "setosa2" = NA
)
   Species   num Values_From  setosa1 setosa2
   <chr>   <int> <chr>        <lgl>   <lgl>  
 1 setosa      1 Sepal.Length NA      NA     
 2 setosa      1 Sepal.Width  NA      NA     
 3 setosa      1 Petal.Length NA      NA     
 4 setosa      1 Petal.Width  NA      NA     
 5 setosa      2 Sepal.Length NA      NA     
 6 setosa      2 Sepal.Width  NA      NA     
 7 setosa      2 Petal.Length NA      NA     
 8 setosa      2 Petal.Width  NA      NA     
 9 setosa      3 Sepal.Length NA      NA     
10 setosa      3 Sepal.Width  NA      NA  

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

看起来您需要先使数据变长 (pivot_longer),然后再变宽。此外,似乎 num 列不值得保留。如果您想保留 num 列,请从下面的代码中删除 select(-num) %>%

iris2 %>%
    select(-num) %>%
    pivot_longer(cols = Sepal.Length:Petal.Width) %>%
    pivot_wider(names_from = ID, values_from = value)

  Species name         setosa1 setosa2 setosa3
  <fct>   <chr>          <dbl>   <dbl>   <dbl>
1 setosa  Sepal.Length     5.1     4.9     4.7 ...
2 setosa  Sepal.Width      3.5     3       3.2 ...
3 setosa  Petal.Length     1.4     1.4     1.3 ...
4 setosa  Petal.Width      0.2     0.2     0.2 ...

答案 1 :(得分:2)

也许这会有所帮助:

library(dplyr)
library(tidyr)
#Code
#Code
iris2 %>% pivot_longer(-c(Species,num,ID)) %>%
  pivot_wider(names_from = ID,values_from=value)

输出:

# A tibble: 40 x 13
   Species   num name  setosa1 setosa2 setosa3 setosa4 setosa5 setosa6 setosa7 setosa8
   <fct>   <int> <chr>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
 1 setosa      1 Sepa~     5.1    NA      NA        NA      NA      NA      NA      NA
 2 setosa      1 Sepa~     3.5    NA      NA        NA      NA      NA      NA      NA
 3 setosa      1 Peta~     1.4    NA      NA        NA      NA      NA      NA      NA
 4 setosa      1 Peta~     0.2    NA      NA        NA      NA      NA      NA      NA
 5 setosa      2 Sepa~    NA       4.9    NA        NA      NA      NA      NA      NA
 6 setosa      2 Sepa~    NA       3      NA        NA      NA      NA      NA      NA
 7 setosa      2 Peta~    NA       1.4    NA        NA      NA      NA      NA      NA
 8 setosa      2 Peta~    NA       0.2    NA        NA      NA      NA      NA      NA
 9 setosa      3 Sepa~    NA      NA       4.7      NA      NA      NA      NA      NA
10 setosa      3 Sepa~    NA      NA       3.2      NA      NA      NA      NA      NA
# ... with 30 more rows, and 2 more variables: setosa9 <dbl>, setosa10 <dbl>

答案 2 :(得分:1)

我们可以使用 recast 中的 reshape2

library(reshape2)
recast(iris2, id.var = c("Species", "num", "ID"), 
       Species + num + variable ~ ID, value.var = 'value')

-输出

# Species num     variable setosa1 setosa10 setosa2 setosa3 setosa4 setosa5 setosa6 setosa7 setosa8 setosa9
#1   setosa   1 Sepal.Length     5.1       NA      NA      NA      NA      NA      NA      NA      NA      NA
#2   setosa   1  Sepal.Width     3.5       NA      NA      NA      NA      NA      NA      NA      NA      NA
#3   setosa   1 Petal.Length     1.4       NA      NA      NA      NA      NA      NA      NA      NA      NA
#4   setosa   1  Petal.Width     0.2       NA      NA      NA      NA      NA      NA      NA      NA      NA
#5   setosa   2 Sepal.Length      NA       NA     4.9      NA      NA      NA      NA      NA      NA      NA
#6   setosa   2  Sepal.Width      NA       NA     3.0      NA      NA      NA      NA      NA      NA      NA
# ...

答案 3 :(得分:1)

dcast 中的 melt + data.table 的组合可能会有所帮助

iris3 <- dcast(melt(setDT(iris2), id = c("Species", "num", "ID")), ... ~ ID, value.var = "value")

这样

> head(iris3)
   Species num     variable setosa1 setosa10 setosa2 setosa3 setosa4 setosa5
1:  setosa   1 Sepal.Length     5.1       NA      NA      NA      NA      NA
2:  setosa   1  Sepal.Width     3.5       NA      NA      NA      NA      NA
3:  setosa   1 Petal.Length     1.4       NA      NA      NA      NA      NA
4:  setosa   1  Petal.Width     0.2       NA      NA      NA      NA      NA
5:  setosa   2 Sepal.Length      NA       NA     4.9      NA      NA      NA
6:  setosa   2  Sepal.Width      NA       NA     3.0      NA      NA      NA
   setosa6 setosa7 setosa8 setosa9
1:      NA      NA      NA      NA
2:      NA      NA      NA      NA
3:      NA      NA      NA      NA
4:      NA      NA      NA      NA
5:      NA      NA      NA      NA
6:      NA      NA      NA      NA