2017-08-04 43 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