【问题标题】:How to filter overlap rows in a big file with R如何使用R过滤大文件中的重叠行
【发布时间】:2013-06-21 08:58:37
【问题描述】:

我正在尝试使用 R 过滤大文件中的重叠行。重叠度设置为 25%。换句话说,任何两行之间的交集元素的数量小于它们并集的0.25倍。如果大于0.25,则删除一行。所以如果我有一个总共有1000 000行的大文件,第一个5行如下:

c6 c24 c32 c54 c67
c6 c24 c32 c51 c68 c78
c6 c32 c54 c67
c6 c32 c55 c63 c85 c94 c75
c6 c32 c53 c67

因为第一行和第二行相交的元素个数为3,(如c6,c24,c32),所以它们之间的并集数为8,(如c6,c24,c32,c54, c67,c51,c68,c78),3/8=0.375 > 0.25,第2行被删除。第3和第5行也是如此。最终答案是第1和第4行。

c6 c24 c32 c54 c67
c6 c32 c55 c63 c85 c94 c75

伪代码如下:

for i=1:(n-1)    # n is the number of rows of a file
    for j=(i+1):n  
        if  overlap degrees of the ith row and jth row is more than 0.25
          delete the jth row from the file
        end
   end

结束

R代码如下:

   con<-file("inputfile.txt","r")
   fileConn<-file("outputfile025.txt")
   data<-readLines(con,n=1) 
   con1<-strsplit(data,"\t") 
   writeLines(con1[[1]][], fileConn)

   for(i in 2:1000000){
   data<-readLines(con,n=1) 
   con2<-strsplit(data,"\t")

    intersect=length(intersect(con1[[1]][],con2[[1]][]))
    union =length(union(con1[[1]][],con2[[1]][]))

   if ((intersect/union)<0.25){
    writeLines(con2[[1]][], fileConn)
   }

   }
   close(con)
   close(fileConn)

问题是上面的代码只能用来过滤第1行和其他行的重叠,如何过滤第2、3、......行和其他行之间的重叠。有谁知道如何解决这个问题?谢谢!

【问题讨论】:

  • 我不是很清楚...在第一行与所有其他行进行比较后,您是否要将第二行与所有其他行进行比较?那么第三排呢?如果是,请注意最终输出将取决于比较行的顺序。例如。如果按 1、3、2 的顺序比较行,比较第 1、2、3 行的输出可能会有所不同
  • 您可以使用expand.grid 获取行组合(注意重复)并循环遍历。
  • 我不确定您的问题是否明确。例如,在您过滤与第一行比较的文件后,您会从现在修剪的文件开始吗?或者与第二行的比较会是另一个输出文件吗?
  • 我添加了一些关于我的问题的解释。

标签: r overlap


【解决方案1】:

这是一个使用agrep 的解决方案,该解决方案使用广义的 Levenshtein 编辑距离近似匹配列表的其他元素中的模式(这里是列表的一个元素):

max.distance=list(deletions=0.25)

例如,使用lapply 循环遍历您的数据:

res <- unlist(lapply(seq_along(ll),function(x){
  res <- agrep(pattern=ll[x],         # for each string
              ll[-x],                # I search between the others strings 
              value=FALSE,max=list(deletions=0.25))  # I set the Levenshtein distance
  if(length(res)==0) NA else res
}))
ll[res[!is.na(res) & duplicated(res)]]

"c6 c24 c32 c54 c67"         
"c6 c32 c54 c67"             
"c6 c32 c55 c63 c85 c94 c75"

然后你可以删除重复和缺失的值:

PS:这里ll 是:

ll <- readLines(textConnection(object='c6 c24 c32 c54 c67
c6 c24 c32 c51 c68 c78
c6 c32 c54 c67
c6 c32 c55 c63 c85 c94 c75
c6 c32 c53 c67'))

【讨论】:

  • 我添加了一些关于我的问题的解释。
  • @user2405694 你的伪代码不清楚。您想将 1 与其他人进行比较,而不是将 2 与其他人进行比较[-1]、3 与其他人进行比较[-c(1,2)],..?
  • @user2405694 那么你想这样做吗:1 to others ; 2 to others[-c(1,overlapped1)]; 3 to others[-c(1,2,overlapped1,overlapped2)],..? ——
猜你喜欢
  • 2020-03-25
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 2022-01-09
  • 1970-01-01
  • 2020-09-11
  • 2021-03-15
相关资源
最近更新 更多