在r中删除大数据集中的行的问题

时间:2014-02-18 16:05:14

标签: r

我编写了一个脚本,删除了20%的单元格小于10的行。 它在小型数据集上运行得很好但是对于大型数据集来说它没用。 可以用sombody帮我。

这是我的剧本:

     DataSets<-choose.files()

     DataSet<-read.delim(DataSets,header = TRUE,
     row.names = 1,sep="\t",blank.lines.skip=TRUE)

     delete<-0
     for(i in 1:length(DataSet[,1]))
      {
       count<-0
       for(j in 1:length(DataSet[i,]))
       {
         if(DataSet[i,j]<10 || is.na(DataSet[i,j]))
        {
           count=count+1
        }
       }
       if(count>0.2*length(DataSet[i,]))
       {
         DataSet=DataSet[-i,]
         delete<-delete+1
       } 
     }

3 个答案:

答案 0 :(得分:5)

这在我的机器上基本上是即时的:

m <- matrix(runif(100000),10000,10)
system.time(m1 <- m[rowSums((m <= 0.25 | is.na(m)) < 2,])

我只是近似你的确切情况,但你的版本是类似的。这里的想法是:

  1. 如果您的数据确实都是数字,请使用矩阵而不是数据框。
  2. 使用矢量化比较来确定哪些元素小于某个值(在我的示例中为0.25)。
  3. 然后使用rowSums计算每行中少于0.25的值。
  4. 根据行少于两个小于(或等于)0.25的值来设置矩阵。
  5. 编辑添加了对NAs的检查以对其进行计数。

答案 1 :(得分:3)

这可以解决您的问题。您可以将数据保留为DataFrame。

    dat<-data.frame(matrix(rnorm(100,10,1),10))
    bad<-apply(dat,1,function(x){
      return((sum(x<10,na.rm=TRUE)+sum(is.na(x)))>length(x)*0.2)
      })
    dat<-dat[!bad,]

答案 2 :(得分:1)

这对我来说非常快。像@joran使用的解决方案一样,我使用矩阵:

data <- matrix(rnorm(1000, 15, 5), 100, 10)
tf <- apply(data, 1, function(x) x < 10) # your value of 10
data[-which(colSums(tf) > ncol(data)*0.2),] # here is where the 20% comes in

TRUE = 1且FALSE = 0,这就是为什么人们可以在这里使用colSums

处理NAs的更新

如果OP的评论包含“仅20%的数值”,而不是原始代码将NA值计为值&lt; 10,(即删除20%的数字条目小于10的行),这将起作用:

data[-which(colSums(tf, na.rm=T) > (ncol(data) - colSums(apply(tf,2,is.na)))*0.2),]

colSums(apply(tf,2,is.na))计算data行中NA的条目数。

(ncol(data) - colSums(apply(tf,2,is.na)))从列数中减去该数字,以便只返回数字列的总数。

(ncol(data) - colSums(apply(tf,2,is.na)))*0.2是每行数字条目数的20%