2016-11-12 47 views
0

第一個字符串我有這樣如何保持每行

df1 <- structure(list(V1 = structure(c(1L, 2L, 3L, 5L, 4L), .Label = c("A0A061ACH4;Q95Q10;Q9U1W6", 
"A0A061ACL3;Q965I6;O76618", "A0A061ACR1;Q2XN02;F5GUA3;Q22498", 
"A0A061AL01", "H2FLH3;H2FLH2;A0A061ACT3;A0A061AE24;Q23551-2;Q23551;Q23551-4;Q23551-3;Q23551-5" 
), class = "factor"), V2 = c(1L, 5L, 100L, 645L, 11L), V3 = c(67L, 
10L, 33L, 99L, 10L), V4 = c(7L, 16L, 0L, 1L, 5L)), .Names = c("V1", 
"V2", "V3", "V4"), class = "data.frame", row.names = c(NA, -5L 
)) 

我要的是一個數據,保證把所有的琴絃下對方,在每行前面複製的價值,前面在該行每個字符串
預期的輸出應該喜歡這個

output <- structure(list(V1 = structure(c(1L, 18L, 20L, 2L, 19L, 19L, 10L, 
3L, 17L, 7L, 11L, 9L, 8L, 4L, 5L, 13L, 12L, 15L, 14L, 16L, 6L 
), .Label = c("A0A061ACH4", "A0A061ACL3", "A0A061ACR1", "A0A061ACT3", 
"A0A061AE24", "A0A061AL01", "F5GUA3", "H2FLH2", "H2FLH3", "O76618", 
"Q22498", "Q23551", "Q23551-2", "Q23551-3", "Q23551-4", "Q23551-5", 
"Q2XN02", "Q95Q10", "Q965I6", "Q9U1W6"), class = "factor"), V2 = c(1L, 
1L, 1L, 5L, 5L, 5L, 5L, 100L, 100L, 100L, 100L, 645L, 645L, 645L, 
645L, 645L, 645L, 645L, 645L, 645L, 11L), V3 = c(67L, 67L, 67L, 
10L, 10L, 10L, 10L, 33L, 33L, 33L, 33L, 99L, 99L, 99L, 99L, 99L, 
99L, 99L, 99L, 99L, 10L), V4 = c(7L, 7L, 7L, 16L, 16L, 16L, 16L, 
0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 5L)), .Names = c("V1", 
"V2", "V3", "V4"), class = "data.frame", row.names = c(NA, -21L 
)) 

例如,如果我們看一下DF1第一線,它看起來像這樣

A0A061ACH4;Q95Q10;Q9U1W6 1 67 7 

然後我分割後的字符串;並將它們置於彼此之下並將值複製到它們的前面。所以對於DF1的第一行,我會

A0A061ACH4 1 67 7 
    Q95Q10  1 67 7 
    Q9U1W6  1 67 7 
+1

請注意,您的預期產出存在輕微錯誤。結果應該是20行。 –

回答

1

這是一個「基礎」的方式。

# for each line... 
out <- do.call(rbind, apply(df1, MARGIN = 1, FUN = function(x) { 
    # split by ; and... 
    do.call(rbind, sapply(unlist(strsplit(x[1], ";")), FUN = function(y, y2) { 
    # ... append the rest of the columns to individual element 
    c(y, y2) 
    }, simplify = FALSE, y2 = x[2:4])) 
    })) 

rownames(out) <- NULL 

out <- as.data.frame(out) 

out 

      V1 V2 V3 V4 
1 A0A061ACH4 1 67 7 
2  Q95Q10 1 67 7 
3  Q9U1W6 1 67 7 
4 A0A061ACL3 5 10 16 
5  Q965I6 5 10 16 
6  O76618 5 10 16 
7 A0A061ACR1 100 33 0 
8  Q2XN02 100 33 0 
9  F5GUA3 100 33 0 
10  Q22498 100 33 0 
11  H2FLH3 645 99 1 
12  H2FLH2 645 99 1 
13 A0A061ACT3 645 99 1 
14 A0A061AE24 645 99 1 
15 Q23551-2 645 99 1 
16  Q23551 645 99 1 
17 Q23551-4 645 99 1 
18 Q23551-3 645 99 1 
19 Q23551-5 645 99 1 
20 A0A061AL01 11 10 5 
2

這可以separate_rowstidyr

library(tidyr) 
separate_rows(df1, V1, sep=";") 

完成,或者使用cSplitlong選項

library(splitstackshape) 
cSplit(df1, 'V1', ';', 'long') 

或者使用其他base R選項

lst <- strsplit(as.character(df1$V1), ";") 
cbind(V1= unlist(lst), df1[rep(1:nrow(df1), lengths(lst)),-1]) 

如果我們只需要第一;前的子字符串,使用sub到後面的字符模式;匹配直到字符串(.*)的末端,更換與空白("")。

df1$V1 <- sub(";.*", "", df1$V1) 
+0

有沒有其他方式不使用包?也可以不重複,只是刪除其他字符串之後;從每一行開始並保持每行第一行? –

+0

@LearnerAlgorithm是的,這是可能的(''df1 $ V1 < - sub(「;。*」,「」,df1 $ V1)') ,但我看着你的期望輸出('output')它顯示 – akrun

+0

謝謝,以上人給了我一個沒有任何包使用的解決方案!我無法爲你感謝你,因爲我是新來的,我沒有聲望:-( –