2017-02-24 24 views
0

我有2列(「X」和「Y」),看起來像這樣一個data.frame:從data.frame刪除行,其中字符串共享一個通用模式的兩側內的數字不匹配

X   Y 
1_SNP_3 4 
2_SNP_6 3 
3_SNP_1 4 
20_SNP_7 7 
7_SNP_20 7 

在R中使用grepl或類似的函數,我想比較X中的所有元素(字符串)。每個字符串在開頭和結尾都有一個數字,所有字符串之間共享一個公共子字符串模式(「__SNP_」 )。我想只刪除那些當同一個字符串內的數字被反轉時(例如從1_SNP_3到3_SNP_1)形成重複字符串的行。

例如如果「1_SNP_3」中的數字被反轉,則結果字符串「3_SNP_1」已存在,所以這些字符串中的一個(以及相應的行)被刪除。

我會得到這樣的:

X   Y 
1_SNP_3 4 
2_SNP_6 3 
20_SNP_7 7 
+0

爲什麼'2_SNP_6'是結果的解決方案? – zx8754

+1

@ zx8754因爲沒有6_SNP_2任何地方 – Lucas

+1

在「_」上分割(關於「如何分割分隔刺」有很多解決方案),然後將第一個和第三個數字轉換爲數字,排序這兩個數字,使用粘貼重新聲明SNP名稱,並獲得獨特。嘗試,如果遇到問題,請更新您的帖子。 – zx8754

回答

3

這裏使用的基礎R.

df[!duplicated(sapply(strsplit(gsub('\\D+', ' ', df$X), ' '), function(i) toString(sort(i)))),] 
#   X Y 
#1 1_SNP_3 4 
#2 2_SNP_6 3 
#4 20_SNP_7 7 
2
# My first answer submission - A data table solution 
# create the table 
DT <- data.table(X = c("1_SNP_3","2_SNP_6","3_SNP_1","20_SNP_7","7_SNP_20"), 
           Y = c(4,3,4,7,7)) 
DT 
# Extract first and last numbers 
DT[, ':=' (B = gsub("_.*","",X), 
       E = gsub(".*_SNP_","",X))] 
# Order the new columns so B is always less than E 
DT[DT$B > DT$E , c("B", "E")] <- DT[DT$B > DT$E , c("E", "B")] 

# Keep only the first instance , so delete duplicates 
DT <- DT[, .SD[1], by=c("B","E")] 
# Delete extra columns 
DT [,c("B","E") := NULL] 
DT 

Answer :  
    X Y 
1: 1_SNP_3 4 
2: 2_SNP_6 3 
3: 20_SNP_7 7 
相關問題