2017-10-08 33 views
1

我想传播()一对键/值对,但公用值列不会折叠。我认为它可能与之前的一些处理有关,或者更可能我不知道传播两个或更多键/值对以获得我期望的结果的正确方法。r tidyverse传播()使用多个键值对不折叠行

我开始与这组数据:

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蔓延预先步骤来定义在以下收集()函数创建的“计数”值的顺序。这是第一个扩展预步骤来定义“计数”使用可变的行数量的原始顺序:

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

这是第二个扩展预步骤来定义的“计数”的数值顺序可变:

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 

我已审查的问题和答案关于使用重复标识符以及使用行号索引进行传播,但这无济于事。

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

感谢您的帮助。

回答

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 
+0

谢谢ycw那完美的工作。我不确定我是否完全理解,但我喜欢它坚持纯粹的方法论;我会更多地研究这一点。再次感谢。 –

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