【问题标题】:r tidyverse spread() using multiple key value pairs not collapsing rowsr tidyverse spread() 使用多个键值对不折叠行
【发布时间】:2017-10-08 01:37:06
【问题描述】:

我正在尝试 spread() 几个键/值对,但公共值列没有折叠。我认为这可能与之前的一些处理有关,或者我更可能不知道传播两个或多个键/值对以获得我期望的结果的正确方法。

我从这个数据集开始:

library(tidyverse)

df <- tibble(order = 1:7,
             line_1 = c(23,8,21,45,68,31,24),
             line_2 = c(63,25,25,24,48,24,63),
             line_3 = c(62,12,10,56,67,25,35))

有 2 个预传播步骤来定义在以下收集 () 函数中创建的“计数”值的顺序。这是使用行号定义“count”变量的原始顺序的第一个预扩展步骤:

ntrl <- df %>%
           gather(line_1,
                  line_2,
                  line_3,
                  key = "sector",
                  value = "count") %>%
           group_by(order) %>%
           mutate(sector_ord = row_number()) %>%
           arrange(order,
                   sector)

这是定义“count”变量的数字顺序的第二个预传播步骤:

ord <- ntrl %>%
            arrange(order,
                    count) %>%
            group_by(order) %>%
            mutate(num_ord = paste0("ord_",
                                    row_number(),
                                    sep=""))

最后是我一直在使用的传播代码:

wide <- ord %>%
            group_by(order) %>%
            spread(key = sector,
                   value = count) %>%
            spread(key = num_ord,
                   value = sector_ord)

我得到的是这样的:

    order   line_1  line_2  line_3  ord_1   ord_2   ord_3                           
1   1       23      NA      NA      1       NA      NA
2   1       NA      63      NA      NA      NA      2
3   1       NA      NA      62      NA      3       NA
4   2       8       NA      NA      1       NA      NA
5   2       NA      25      NA      NA      NA      2
6   2       NA      NA      12      NA      3       NA
7   3       21      NA      NA      NA      1       NA
8   3       NA      25      NA      NA      NA      2
9   3       NA      NA      10      3       NA      NA
... and so on thru 21 lines accounting for all 7 "order" lines

我期望的行为是“订单”列会在所有具有相同“订单”值的行中折叠以提供以下内容:

    order   line_1  line_2  line_3  ord_1   ord_2   ord_3                           
1   1       23      63      62      1       3       2
2   2       8       25      12      1       3       2
3   3       21      25      10      2       3       1
4   4       45      24      56      2       1       3
... and so on, I think that paints the picture

我已经查看了有关使用重复标识符进行传播和使用行号索引的问题和答案,但这并没有帮助。

我认为这与双重传播有关,但我不知道该怎么做。

感谢您的帮助。

【问题讨论】:

    标签: r tidyverse spread


    【解决方案1】:

    使用tidyverse 启动您的df 的解决方案。关键是使用summarise_all(funs(.[which(!is.na(.))])) 为每列选择唯一的非NA 值。

    library(tidyverse)
    
    df2 <- df %>%
      gather(Lines, Value, -order) %>%
      group_by(order) %>%
      mutate(Rank = dense_rank(Value), 
             RankOrder = paste0("ord_", row_number())) %>%
      spread(Lines, Value) %>%
      spread(RankOrder, Rank) %>%
      summarise_all(funs(.[which(!is.na(.))]))
    df2
    # A tibble: 7 x 7
      order line_1 line_2 line_3 ord_1 ord_2 ord_3
      <int>  <dbl>  <dbl>  <dbl> <int> <int> <int>
    1     1     23     63     62     1     3     2
    2     2      8     25     12     1     3     2
    3     3     21     25     10     2     3     1
    4     4     45     24     56     2     1     3
    5     5     68     48     67     3     1     2
    6     6     31     24     25     3     1     2
    7     7     24     63     35     1     3     2
    

    【讨论】:

    • 感谢 ycw 完美运行。我不确定我是否完全理解,但我喜欢它坚持 tidyverse 方法;我将对此进行更多研究。再次感谢。
    • @www 如果允许丢失数据,即存在不完整的情况,但期望的结果仍然是每个订单一行,这将如何改变?
    • @MartinSöderström 不确定您在问什么。如果您愿意,请用可重复的示例提出一个新问题。
    • 如果任何列都包含某个摸索变量的所有 NA,则此解决方案不起作用。
    【解决方案2】:

    df开始:

    df %>% 
        gather(headers, line, -order) %>% 
        separate(headers, into = c('dummy', 'rn')) %>% 
        select(-dummy) %>% 
        group_by(order) %>% 
        mutate(ord = rank(line, ties.method='first')) %>% 
        {data.table::dcast(setDT(.), order ~ rn, value.var = c("line", "ord"))}
    
    #   order line_1 line_2 line_3 ord_1 ord_2 ord_3
    #1:     1     23     63     62     1     3     2
    #2:     2      8     25     12     1     3     2
    #3:     3     21     25     10     2     3     1
    #4:     4     45     24     56     2     1     3
    #5:     5     68     48     67     3     1     2
    #6:     6     31     24     25     3     1     2
    #7:     7     24     63     35     1     3     2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-19
      • 1970-01-01
      • 2013-05-22
      • 2019-12-31
      • 2015-09-25
      • 2021-03-03
      • 2015-08-08
      • 1970-01-01
      相关资源
      最近更新 更多