试图获得"计数"对于指定数量的观察,看起来这些函数中的每一个都起作用,因为它们得到相同的结果。但是这些功能在后台如何以不同的方式运行,以及在哪种情况下将一个功能换成另一个呢?
sum(grade.data$Quiz >= (100*.45))
length(which(grade.data$Quiz >= (100*.45)))
nrow(grade.data[grade.data$Quiz >= (100*.45),])
答案 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选择/子集化将数据框架子集化为水。