【问题标题】:Calculate all variable combinations and the distinct counts of df using R data.table使用 R data.table 计算所有变量组合和 df 的不同计数
【发布时间】:2018-12-21 17:43:14
【问题描述】:

如何使用 data.table 以所有可能的 m 运行 comboGeneral 以获得所有可能的变量组合?那么,如何计算使用这些变量组合子集的所有数据帧中的不同计数?

这是一个 purrr 和 dplyr 版本。我需要使用 data.table 的 nms 和计数。

library(data.table); library(dplyr); library(magrittr); library(RcppAlgos); library(purrr)

num_m <- seq_len(ncol(mtcars))
nam_list <- names(mtcars)

nms <- map(num_m, ~comboGeneral(nam_list, m = .x, FUN = c)) %>% unlist(recursive = FALSE)

counts <- map_dbl(nms, ~(mtcars %>% select(.x) %>% n_distinct()))

【问题讨论】:

    标签: r dplyr data.table purrr


    【解决方案1】:

    不清楚您希望通过专门针对第一部分使用data.table 来完成什么。 comboGeneral 来自 RccpAlgos,所以我认为它已经进行了相当大的优化...... combn in base R 是替代方案(这实际上并不是 data.table 的任何实现......):

    nms = unlist(lapply(num_m, combn, x = nam_list, simplify = FALSE), recursive = FALSE)
    

    有了这个,data.table 有几种方法:

    mtcars = as.data.table(mtcars)
    counts = sapply(nms, uniqueN, x = mtcars)
    

    或者

    sapply(nms, function(nm) nrow(mtcars[ , TRUE, keyby = nm]))
    

    或者

    sapply(nms, function(nm) nrow(unique(mtcars, by = nm)))
    

    看来第一种方案不仅最简洁而且效率最高:

    library(microbenchmark)
    
    microbenchmark(times = 100L,
                   map_dbl(nms, ~(mtcars %>% select(.x) %>% n_distinct())),
                   sapply(nms, uniqueN, x = mtcars),
                   sapply(nms, function(nm) nrow(mtcars[ , TRUE, keyby = nm])),
                   sapply(nms, function(nm) nrow(unique(mtcars, by = nm))))
    # Unit: milliseconds
    #                                                        expr        min         lq
    #     map_dbl(nms, ~(mtcars %>% select(.x) %>% n_distinct())) 2246.10862 2365.33801
    #                            sapply(nms, uniqueN, x = mtcars)   66.16144   68.95391
    #  sapply(nms, function(nm) nrow(mtcars[, TRUE, keyby = nm])) 1659.20425 1701.79188
    #     sapply(nms, function(nm) nrow(unique(mtcars, by = nm)))  102.42203  106.87100
    #        mean     median         uq       max neval
    #  2469.50648 2448.44821 2544.00350 3530.6513   100
    #    73.28518   71.54861   75.85161  118.5919   100
    #  1796.30372 1766.59618 1825.97374 2881.2376   100
    #   113.63032  111.28377  118.22441  174.2691   100
    

    关于加速第一步,你可以通过去掉map的糖和生lapply来获得大约10%的加速:

    microbenchmark(times = 1000L,
                   lapply(num_m, combn, x = nam_list, simplify = FALSE),
                   map(num_m, ~comboGeneral(nam_list, m = .x, FUN = c)),
                   lapply(num_m, function(m) comboGeneral(nam_list, m, FUN = c)))
    # Unit: microseconds
    #                                                           expr      min        lq
    #           lapply(num_m, combn, x = nam_list, simplify = FALSE) 1718.994 1847.3710
    #           map(num_m, ~comboGeneral(nam_list, m = .x, FUN = c))  564.076  629.5120
    #  lapply(num_m, function(m) comboGeneral(nam_list, m, FUN = c))  473.135  525.2655
    #       mean    median        uq      max neval
    #  2088.7454 1921.8840 2016.0275 7789.501  1000
    #   713.8342  661.0455  709.4650 3800.253  1000
    #   593.7732  550.2460  583.7005 5190.982  1000
    

    注意:我们不能使用lapply(num_m, comboGeneral, v = nam_list, FUN = c),因为FUN 将被解释为lapply 的参数,而不是comboGeneral

    【讨论】:

    • 这是非常详细和有用的回复!欣赏它!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-03-22
    • 2020-03-26
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    相关资源
    最近更新 更多