过滤数据框以保留符合特定条件的行

时间:2016-01-06 01:11:31

标签: r dataframe

我有以下数据框,我正在尝试过滤。我只想保留行中至少有一个值大于0.5的行。任何帮助表示赞赏。 我尝试执行以下操作,但我的系统挂起:

gbpre.mat<-as.matrix(gbpre)
ind <- apply(gbpre.mat, 1, function(gbpre.mat) any(gbpre > 0.5))

PH1544_pre PH1545_pre PH1565_pre PH1571_pre PH1612_pre  PH1616_pre
bg00050873 0.88235087  0.6053853  0.6521263  0.2770632 0.82596713 0.635325831
bg00212031 0.01175069  0.1844859  0.4345596  0.2186097 0.03717635 0.670305781
bg00213748 0.64571987  0.7316865  0.4345596  0.5613724 0.81309068 0.900878028
bg00214611 0.04405524  0.7103071  0.6810916  0.6526317 0.03412550 0.008187867
bg00455876 0.72122206  0.1272784  0.2155168  0.4794622 0.70089805 0.668497074
bg01707559 0.03592823  0.3548602  0.2743443  0.2194279 0.57761264 0.061564411

1 个答案:

答案 0 :(得分:2)

ind的定义不起作用的原因是,在您应用的函数中,您没有使用函数的参数,而是整个gbpre。如果矩阵很大,这可能会很慢,因为对于矩阵的许多行中的每一行,都会检查整个大矩阵。

更具体一点:这是你的定义:

ind <- apply(gbpre.mat, 1, function(gbpre.mat) any(gbpre > 0.5))

您在行上使用apply,这很好。然后定义一个参数的函数。该参数称为gbpre.mat,这是可能的,但我建议您不要使用与要传递给函数的变量相同的名称。这样可以避免一些混乱。该函数甚至不使用gbpre.mat,因此函数的结果与其输入无关。这不是你想要的。

所以你应该使用以下内容:

ind <- apply(gbpre.mat, 1, function(gb) any(gb > 0.5))

这有效,但是thelatemail建议的实际上更快。让我举个例子。首先,我创建了一个相当大的样本矩阵:

set.seed(1435)
gbpre.mat <- matrix(runif(600000,0,0.7), ncol = 6)
head(gbpre.mat)
##            [,1]        [,2]       [,3]       [,4]         [,5]       [,6]
## [1,] 0.34588950 0.548891207 0.14621109 0.64827636 0.2132974880 0.08318449
## [2,] 0.08258421 0.504511182 0.15966061 0.65975977 0.0009340659 0.18353030
## [3,] 0.01970881 0.004321273 0.51373098 0.58779409 0.1166218414 0.55205101
## [4,] 0.16150403 0.134012891 0.19062268 0.68766140 0.4341565775 0.46083298
## [5,] 0.32099279 0.371436278 0.13317573 0.02674299 0.4670175053 0.47581938
## [6,] 0.50144544 0.579256903 0.03034916 0.56547615 0.0091638700 0.42943656

然后我使用两种方式来获取行,其中至少有一个数字大于0.5并测量时间:

system.time(ind <- apply(gbpre.mat, 1, function(gb) any(gb > 0.5)))
##    user  system elapsed 
##   0.218   0.008   0.228 
system.time(ind2 <- rowSums(gbpre.mat > 0.5) > 0)
##    user  system elapsed 
##   0.008   0.000   0.008

这里有明显的赢家。结果完全相同:

identical(ind, ind2)
## [1] TRUE

我还想补充一些关于你的代码速度慢的原因。让我在矩阵的前600行中运行ind的定义:

system.time(ind3 <- apply(gbpre.mat[1:600, ], 1, function(gb) any(gbpre.mat > 0.5)))
##    user  system elapsed 
##   3.011   0.461   3.479 

你看我在函数中也使用了整个矩阵gbpre.mat。仅运行600行需要3.5秒,整个矩阵的计算大约需要一个小时。这是错误的:你只会得到一个TRUE的向量,因为你实际上已经多次检查过整个矩阵中是否存在大于0.5的单个值。