从data.frame中删除行,其中共享公共模式的字符串的相对两侧的数字匹配

时间:2017-02-24 20:55:10

标签: r string dataframe grepl

我有一个带有2列(“X”和“Y”)的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)时形成重复字符串的那些行。

e.g。如果“1_SNP_3”中的数字被反转,则字符串“3_SNP_1”结果已经存在,因此其中一个字符串(以及相应的行)被删除。

我会得到这个:

X          Y
1_SNP_3    4
2_SNP_6    3
20_SNP_7   7 

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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