2017-08-04 42 views
0

我找的到了unpivot一個基礎R解決方案,我的子串原始數據集。下面的例子;的R - 逆透視及子

ID L1 L2 L3 
1 AABBCC BACA  
2 AAAAAA BACBA CACCC 
3 BBACB BACA CABAC 
4   
5 BCBDAB ACAA CBABA 

dput(original_data): 
structure(list(ID = 1:5, L1 = structure(c(3L, 2L, 4L, 1L, 5L), .Label = c("","AAAAAA", "AABBCC", "BBACB", "BCBDAB"), class = "factor"), L2 = structure(c(3L,4L, 3L, 1L, 2L), .Label = c("", "ACAA", "BACA", "BACBA"), class = "factor"),L3 = structure(c(1L, 3L, 2L, 1L, 4L), .Label = c("", "CABAC","CACCC","CBABA"), class = "factor")), .Names = c("ID", "L1","L2", "L3"),class = "data.frame", row.names = c(NA, -5L)) 

將一個較長的表,同時採取3個重疊的連續字符的子串,下面的例子;

ID Column Position Substring 
1 L1 1 AAB 
1 L1 2 ABB 
1 L1 3 BBC 
1 L1 4 BCC 
1 L1 5 CC 
1 L1 6 C 
1 L2 1 BAC 
1 L2 2 ACA 
1 L2 3 AC 
1 L2 4 A 
2 L1 1 AAA 
2 L1 2 AAA 
2 L1 3 AAA 
2 L1 4 AAA 
2 L1 5 AA 
2 L1 6 A 
2 L2 1 BAC 
2 L2 2 ACB 
2 L2 3 CBA 
2 L2 4 BA 
2 L2 5 A 
2 L3 1 CAC 
2 L3 2 ACC 
2 L3 3 CCC 
2 L3 4 CC 
2 L3 5 C 

有沒有人有任何想法如何做到這一點?我的問題是我不能使用外部庫,如reshap2。我需要在基地r做到這一點。

+0

你的「結構」爲您的樣本數據被打破,它不糊成R正確。你可以再試一次嗎? – Spacedman

+0

謝謝,我想我已經糾正了這一點。現在怎麼樣? –

回答

0

寫,計算一個字符串的子功能。測試:

bits = function(s){ 
    s=as.character(s) 
    substring(s,1:nchar(s),2+(1:nchar(s))) 
} 

> bits("ABCDEF") 
[1] "ABC" "BCD" "CDE" "DEF" "EF" "F" 

現在寫一個函數做單排,它使用lapply在三個大號變量和融合的結果:

dorow = function(rr){ 
    do.call(
     rbind, 
     lapply(1:3, 
       function(L){ 
        s=rr[[paste0("L",L)]] 
        ts = bits(s) 
        data.frame(
         ID=rr[["ID"]], 
         Column=paste0("L",L), 
         Position=1:length(ts), 
         Substring=ts) 
       } 
       ) 
    ) 
} 

測試此:

> dorow(d[1,]) 
    ID Column Position Substring 
1 1  L1  1  AAB 
2 1  L1  2  ABB 
3 1  L1  3  BBC 
4 1  L1  4  BCC 
5 1  L1  5  CC 
6 1  L1  6   C 
7 1  L2  1  BAC 
8 1  L2  2  ACA 
9 1  L2  3  CA 
10 1  L2  4   A 
11 1  L3  1   
12 1  L3  2  

返回一些空白,但我們稍後會解決。

編寫一個函數來遍歷行,叫dorow,並結合。這裏過濾掉空字符串:

dodata = function(d){ 
    dd = do.call(
     rbind, 
     lapply(1:nrow(d), 
       function(r){dorow(d[r,])}) 
    ) 
    dd[dd$Substring!="",] 
} 

和測試...

> d 
    ID  L1 L2 L3 
1 1 AABBCC BACA  
2 2 AAAAAA BACBA CACCC 
3 3 BBACB BACA CABAC 
> head(dodata(d),16) 
    ID Column Position Substring 
1 1  L1  1  AAB 
2 1  L1  2  ABB 
3 1  L1  3  BBC 
4 1  L1  4  BCC 
5 1  L1  5  CC 
6 1  L1  6   C 
7 1  L2  1  BAC 
8 1  L2  2  ACA 
9 1  L2  3  CA 
10 1  L2  4   A 
13 2  L1  1  AAA 
14 2  L1  2  AAA 
15 2  L1  3  AAA 
16 2  L1  4  AAA 
17 2  L1  5  AA 
18 2  L1  6   A 
> 

是否正確?

+0

非常感謝,這個作品非常好!只有兩件事; 1)我仍然得到一些空行,2)此刻,代碼適用於我的示例中提供的列「L1,L2,L3」。如何擴展它以適用於「C1,C2,C3,L1,L2,L3」列?再次感謝 –

+0

我不從你的測試數據得到任何空行,所以你必須的東西,是不是很喜歡您的測試數據來運行它。也許在空格中有空格字符而不是零長度的空字符串?調整'dodata'結尾處的測試以解決問題。 – Spacedman

+0

要處理一組命名列,編輯'dorow'來遍歷列的名稱('lapply(column_names,function(col){...})')並按名稱從'rr'中提取數據('s = rr [[col]]'),並確保在構建行時放入'Column = col'。 – Spacedman