2017-10-08 37 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