考虑以下因素
x = factor(c("1|1","1|0","1|1","1|1","0|0","1|1","0|1"))
我想计算一下角色的出现次数" 0"在这个因素。我到目前为止找到的唯一解决方案是
sum(grepl("0",strsplit(paste(sapply(x, as.character), collapse=""), split="")[[1]]))
# [1] 4
对于这样一个简单的过程,这个解决方案似乎非常复杂。是否有更好的"替代? (由于该过程将在2000个元素长的因素上重复约100,000次,我可能最终也会关注性能。)
答案 0 :(得分:7)
x = factor(c("1|1","1|0","1|1","1|1","0|0","1|1","0|1"))
x
# [1] 1|1 1|0 1|1 1|1 0|0 1|1 0|1
# Levels: 0|0 0|1 1|0 1|1
sum( unlist( lapply( strsplit(as.character(x), "|"), function( x ) length(grep( '0', x ))) ) )
# [1] 4
或
sum(nchar(gsub("[1 |]", '', x )))
# [1] 4
基于@Rich Scriven的评论
sum(nchar(gsub("[^0]", '', x )))
# [1] 4
根据@ thelatemail的评论 - 使用tabulate
的工作速度比上述解决方案快得多。这是比较。
sum(nchar(gsub("[^0]", "", levels(x) )) * tabulate(x))
时间档案:
x2 <- sample(x,1e7,replace=TRUE)
system.time(sum(nchar(gsub("[^0]", '', x2 ))));
# user system elapsed
# 14.24 0.22 14.65
system.time(sum(nchar(gsub("[^0]", "", levels(x2) )) * tabulate(x2)));
# user system elapsed
# 0.04 0.00 0.04
system.time(sum(str_count(x2, fixed("0"))))
# user system elapsed
# 1.02 0.13 1.25
答案 1 :(得分:6)
以下是三个选项。
选项1: sep="|"
使用sum(scan(text=as.character(x), sep="|") == 0)
# [1] 4
gregexpr()
选项2: sum(unlist(gregexpr("0", x, fixed=TRUE)) > 0)
# [1] 4
library(stringr)
sum(str_count(x, fixed("0")))
# [1] 4
选项3 stringr
这是一个非常简单快速的打包选项<param-name>javax.ws.rs.container.ContainerResponseFilter</param-name>