2017-10-20 43 views
1

我有一個看起來像這樣的程序的輸出。R:如何附加數據幀的不同頭部和/或數據幀的溢出部分

Keg  X A D E F 
123F 0 1 0 0 0 
134E 0 0 0 0 1 
234B 0 0 0 0 0 
Keg  G 
123F 0 
134E 0 
234B 1 
Keg  X C D E F 
ABCD 0 1 0 0 0 
13CD 0 0 0 0 1 
234F 0 0 0 1 0 
DCEF 0 0 1 0 0 

我試圖安排這樣

Keg  A C D E F G 
123F 1 0 0 0 0 0 
134E 0 0 0 0 1 0 
234B 0 0 0 0 0 1 
ABCD 0 1 0 0 0 0 
13CD 0 0 0 0 1 0 
234F 0 0 0 1 0 0 
DCEF 0 0 1 0 0 0 

此段文字假設兩個連續keg`s之間的文本作爲一個塊。

在這個例子中,前兩個塊具有相同的桶值。實際上,文本溢出,導致第二個塊具有相同的桶值。每個新的塊(不是溢出塊)都有一個列X.

列X需要在輸出結果證明的最後去掉。列數是有限的,可以假定爲(A,C,D,E,F,G)。

輸出中可以有任意數量的塊。任何溢出的塊將在其家族之下。數據塊總是有列名稱,這些名稱是有限名稱集的一部分。列名不重複。

我們也可以有不同的列名順序的數據塊。

我知道我可以使用bind_row()函數合併兩個不同列名的塊,我知道我可以使用inner_join(),溢出的塊。我無法巧妙地整合這兩個概念。我爲這樣的文本編寫了R代碼,沒有溢出部分。

希望有人能告訴我如何做到這一點。我是R新手,正在爲此而苦苦掙扎。

回答

3

我們split數據集中的「data.frame是基於在大寫字母的發生‘X一list’,通過環路list(」地圖「),與那些第一行字母更改列名,然後我們做與bind_rows單一數據集,通過「凱格」分組,得到其他列

library(tidyverse) 
nm1 <- c("A", "C", "D", "E", "F", "G") 
split(df1, cumsum(grepl("[A-Z]", df1$X))) %>% 
     map(~ if(any(grepl("[A-Z]", .$X))) { 
       names(.) <- unlist(.[1,]) 
       .[-1,] 
     } else .) %>% 
      map(~ .[names(.) != ""]) %>% 
      bind_rows %>% 
      group_by(Keg) %>% 
      summarise_at(vars(nm1), funs(sum(as.numeric(.), na.rm = TRUE))) 

# A tibble: 7 x 7 
# Keg  A  C  D  E  F  G 
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
#1 123F  1  0  0  0  0  0 
#2 134E  0  0  0  0  1  0 
#3 13CD  0  0  0  0  1  0 
#4 234B  0  0  0  0  0  1 
#5 234F  0  0  0  1  0  0 
#6 ABCD  0  1  0  0  0  0 
#7 DCEF  0  0  1  0  0  0 
+1

我不能給予好評的答案,由於名聲小於15 – Acinonyx

+0

有一個Q代表你的sum。上面的解決方案假設nm1矢量中的所有列名正在數據中使用。但是,如果該向量包含的名稱多於使用的名稱,則代碼將引發錯誤。例如,如果我將「H」添加到nm1向量。這會導致錯誤:錯誤:字符串必須匹配列名稱。未知列:H.是否有解決方案。 TIA – Acinonyx

+0

@akrun上面的Q – Acinonyx