【问题标题】:Counting the number of "0" in this factor计算这个因子中“0”的个数
【发布时间】:2017-07-21 13:53:03
【问题描述】:

考虑以下因素

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 次,我可能最终也会关心性能。)

【问题讨论】:

    标签: r string parsing pattern-matching


    【解决方案1】:
    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
    

    【讨论】:

    • 如果您正在处理一个非常大的向量,您可以通过仅对xlevels 进行操作来节省时间 - sum(nchar(gsub("[^0]", "", levels(x) )) * tabulate(x))
    • @thelatemail 谢谢。很高兴知道。它打败了一切
    • 关键是gsub 只需要在length(levels(x)) 而不是length(x) 上运行 - 在这种情况下,正则表达式似乎非常密集。说了这么多,在 15 秒内处理 1000 万条记录仍然非常快。
    【解决方案2】:

    这里有三个选项。

    选项 1: scan() 使用 sep="|" 的向量

    sum(scan(text=as.character(x), sep="|") == 0)
    # [1] 4
    

    选项 2:gregexpr() 中的固定字符

    sum(unlist(gregexpr("0", x, fixed=TRUE)) > 0)
    # [1] 4
    

    选项 3: 一个非常简单快速的打包选项,带有 stringr

    library(stringr)
    sum(str_count(x, fixed("0")))
    # [1] 4
    

    【讨论】:

    • 计时 - set.seed(1); x2 &lt;- sample(x,1e7,replace=TRUE); system.time(sum(nchar(gsub("[^0]", '', x2 )))); system.time(sum(nchar(gsub("[^0]", "", levels(x2) )) * tabulate(x2))); system.time(sum(str_count(x2, fixed("0"))))
    • @thelatemail - levels + tabulate 一个是梦幻的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-15
    • 2021-05-12
    相关资源
    最近更新 更多