【问题标题】:tidyr::spread() with multiple keys and valuestidyr::spread() 具有多个键和值
【发布时间】:2019-05-19 19:52:12
【问题描述】:

我认为这已被多次询问,但我找不到合适的词来找到可行的解决方案。

我如何spread() 一个基于多个值的多个键的数据框?

我正在使用的简化数据(我有更多列要传播,但只有两个键:Idtime 给定测量点)数据如下所示:

df <- data.frame(id = rep(seq(1:10),3), 
                 time = rep(1:3, each=10), 
                 x = rnorm(n=30), 
                 y = rnorm(n=30))

> head(df)
  id time           x           y
1  1    1 -2.62671241  0.01669755
2  2    1 -1.69862885  0.24992634
3  3    1  1.01820778 -1.04754037
4  4    1  0.97561596  0.35216040
5  5    1  0.60367158 -0.78066767
6  6    1 -0.03761868  1.08173157
> tail(df)
   id time           x          y
25  5    3  0.03621258 -1.1134368
26  6    3 -0.25900538  1.6009824
27  7    3  0.13996626  0.1359013
28  8    3 -0.60364935  1.5750232
29  9    3  0.89618748  0.0294315
30 10    3  0.14709567  0.5461084

我想要的是这样填充的数据框:

time 中的每个值和每个测量变量的每个 Id 列都有一行。

【问题讨论】:

    标签: r dataframe reshape tidyr


    【解决方案1】:

    您的条目数据框不整齐。你应该使用 collect 来做到这一点。

    gather(df, key, value, -id, -time) %>%
      mutate(key = paste0(key, "time", time)) %>%
      select(-time) %>%
      spread(key, value)
    

    【讨论】:

    • 在您的收集调用中应该输入什么键和值?当我删除 -id 和 -time 时,没有留下任何钥匙。我弄错了吗?
    • -id-time 表示它们不包含在收集操作中。因此,在收集操作之后,您有以下列:idtimekeyvalue 其中key 将是 x 或 y,value 是相应的值。
    【解决方案2】:

    使用来自data.tabledcast 或来自base Rreshape 最好使用多个值变量进行整形。

    library(data.table)
    out <- dcast(setDT(df), id ~ paste0("time", time), value.var = c("x", "y"), sep = "")
    out
    #    id     xtime1     xtime2      xtime3      ytime1      ytime2      ytime3
    # 1:  1  0.4334921 -0.5205570 -1.44364515  0.49288757 -1.26955148 -0.83344256
    # 2:  2  0.4785870  0.9261711  0.68173681  1.24639813  0.91805332  0.34346260
    # 3:  3 -1.2067665  1.7309593  0.04923993  1.28184341 -0.69435556  0.01609261
    # 4:  4  0.5240518  0.7481787  0.07966677 -1.36408357  1.72636849 -0.45827205
    # 5:  5  0.3733316 -0.3689391 -0.11879819 -0.03276689  0.91824437  2.18084692
    # 6:  6  0.2363018 -0.2358572  0.73389984 -1.10946940 -1.05379502 -0.82691626
    # 7:  7 -1.4979165  0.9026397  0.84666801  1.02138768 -0.01072588  0.08925716
    # 8:  8  0.3428946 -0.2235349 -1.21684977  0.40549497  0.68937085 -0.15793111
    # 9:  9 -1.1304688 -0.3901419 -0.10722222 -0.54206830  0.34134397  0.48504564
    #10: 10 -0.5275251 -1.1328937 -0.68059800  1.38790593  0.93199593 -1.77498807
    

    使用reshape 我们可以做到

    # setDF(df) # in case df is a data.table now
    reshape(df, idvar = "id", timevar = "time", direction = "wide")
    

    【讨论】:

      【解决方案3】:

      使用tidyr (tidyr_0.8.3.9000) 的开发版,我们可以使用pivot_wider 将多个值列从长格式重塑为宽格式

      library(dplyr)
      library(tidyr)
      library(stringr)
      df %>%
         mutate(time = str_c("time", time)) %>%
         pivot_wider(names_from = time, values_from = c("x", "y"), names_sep="")
      # A tibble: 10 x 7
      #      id  xtime1 xtime2  xtime3  ytime1 ytime2 ytime3
      #   <int>   <dbl>  <dbl>   <dbl>   <dbl>  <dbl>  <dbl>
      # 1     1 -0.256   0.483 -0.254  -0.652   0.655  0.291
      # 2     2  1.10   -0.596 -1.85    1.09   -0.401 -1.24 
      # 3     3  0.756  -2.19  -0.0779 -0.763  -0.335 -0.456
      # 4     4 -0.238  -0.675  0.969  -0.829   1.37  -0.830
      # 5     5  0.987  -2.12   0.185   0.834   2.14   0.340
      # 6     6  0.741  -1.27  -1.38   -0.968   0.506  1.07 
      # 7     7  0.0893 -0.374 -1.44   -0.0288  0.786  1.22 
      # 8     8 -0.955  -0.688  0.362   0.233  -0.902  0.736
      # 9     9 -0.195  -0.872 -1.76   -0.301   0.533 -0.481
      #10    10  0.926  -0.102 -0.325  -0.678  -0.646  0.563
      

      注意:数字不同,因为在创建示例数据集时没有设置种子

      【讨论】:

        猜你喜欢
        • 2019-12-31
        • 1970-01-01
        • 1970-01-01
        • 2015-07-22
        • 2017-02-11
        • 2022-01-03
        • 2018-07-27
        • 1970-01-01
        • 2016-05-24
        相关资源
        最近更新 更多