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

Remove rows from data.frame where numbers within opposite sides of strings sharing a common pattern do match

我有一个包含 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

使用 grepl 或 R 中的类似函数,我想比较 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 
# 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

这是一个使用 base 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