r tidyverse spread()使用多个键值对而不是折叠行

时间:2017-10-08 01:37:07

标签: r tidyverse 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个预扩展步骤来定义&#34; count&#34;在以下gather()函数中创建的值。这是定义&#34; count&#34;的原始顺序的第一个预扩展步骤。变量使用行号:

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

这是定义&#34; count&#34;的数字顺序的第二个预扩展步骤。变量:

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

我期待的行为是&#34;命令&#34;列将在所有相同的行中折叠&#34; order&#34;给出以下内容的价值:

    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

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

我认为它与双重传播有关,但我无法弄清楚如何做到这一点。

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

使用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

答案 1 :(得分: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