R中sum(),length(which())和nrow()之间的差异

时间:2014-07-31 17:38:53

标签: r

试图获得"计数"对于指定数量的观察,看起来这些函数中的每一个都起作用,因为它们得到相同的结果。但是这些功能在后台如何以不同的方式运行,以及在哪种情况下将一个功能换成另一个呢?

sum(grade.data$Quiz >= (100*.45))

length(which(grade.data$Quiz >= (100*.45)))

nrow(grade.data[grade.data$Quiz >= (100*.45),])

2 个答案:

答案 0 :(得分:5)

当缺少值时,中间的答案不会给出误导性答案。其他两个都会。

数字1对强制为1&0和0的逻辑向量求和。如果您添加了na.rm,那么当NA存在时它将是有效的。

数字2确定数字向量的长度。

Number 3构造一个子集,然后计算行数。我认为与其他两个相比,它具有相当低的效率,并且具有NA值的问题。如果您将& !is.na(grade.data$Quiz)添加到[ , ]内的逻辑表达式中,您将获得有效答案。

第三种方法(如第三种方法(也是效率低的)没有NA问题)将是:

nrow( subset( grade.data, Quiz >= (100*.45) ) )

答案 1 :(得分:2)

让我们生成100k行data.frame以查看哪种方法最快。

grade.data = data.frame(Quiz = sample(100000), age = sample(18:24, 100000, replace = TRUE))
library(data.table)
dt.grade.data = as.data.table(grade.data)

此处发布的方法

data.table = function(x) dt.grade.data[,sum(Quiz>=100*.45)]
logical.sum = function(x) sum(grade.data$Quiz >= (100*.45))
logical.counting.table = function(x) table(grade.data$Quiz >= (100*.45))[["TRUE"]]
logical.which = function(x) length(which(grade.data$Quiz >= (100*.45)))
subsetting = function(x) nrow(grade.data[grade.data$Quiz >= (100*.45),])
subset.cmd = function(x) nrow(subset(grade.data, Quiz >= (100*.45) ))

基准

microbenchmark(data.table(), logical.sum(), logical.counting.table(), logical.pointless.which(), subsetting(), subset.cmd(), times = 100L)

Unit: microseconds
                   expr       min       lq         median    uq         max        neval
            data.table()      1766.148  2188.8000  2308.267  2469.405  29185.36   100
           logical.sum()       739.385   945.4765   993.921  1074.386  10253.67   100
logical.counting.table()     28867.605 30847.0290 31546.796 32725.255  65514.14   100
         logical.which()       701.205  1080.9555  1138.635  1228.545   3565.96   100
            subsetting()     27376.931 28406.7730 29243.866 30564.371 168034.45   100
            subset.cmd()     29004.315 31203.1730 32219.878 33362.003  89801.34   100

似乎矢量化逻辑检查是最快的方法。在较小的数据帧(500行)中。 data.table实际上比所有其他方法慢得多。

编辑:显然,logical.sum()和logical.which()的相对效率取决于数据结构。使用不同的测验得分分布可以使logical.sum()成为最快的方法。正如预期的那样,data.table选择/子集化将数据框架子集化为水。