【问题标题】:R Counting occurrences per row extremely slowR计数每行的出现非常慢
【发布时间】:2018-05-21 09:46:29
【问题描述】:

我试图在每行的数据框中获取所有出现的值,如下所示:

     a   b  c  d  e
  1  1   1  0 -1 NA
  2  0  -1 -1  1 NA
  3  -1  0 NA NA  1

到这里

     a   b  c  d  e count.-1 count.0 count.1 count.NA
  1  1   1  0 -1 NA        1       1       2        1
  2  0  -1 -1  1 NA        2       1       1        1
  3  1   0 NA NA  1        0       1       2        2

我现在正在这样做:

    df = df %>%
  by_row(
    ..f = function(x) {
      sum(is.na(x[1:8]))
    },
    .to = "count_na",
    .collate = "cols"
  ) %>% 
  by_row(
    ..f = function(x) {
      sum(x[1:8] == 1, na.rm = T)
    },
    .to = "count_positive",
    .collate = "cols"
  ) %>% 
  by_row(
    ..f = function(x) {
      sum(x[1:8] == -1, na.rm = T)
    },
    .to = "count_negative",
    .collate = "cols"
  ) %>% 
  by_row(
    ..f = function(x) {
      sum(x[1:8] == 0, na.rm = T)
    },
    .to = "count_neutral",
    .collate = "cols"
  ) 

但问题是,对于 5 百万行,这需要永远完成(超过 3 小时,有没有更好的方法来做到这一点?

【问题讨论】:

标签: r dataframe dplyr


【解决方案1】:

您可以使用data.table 进行快速处理。首先,融合成一个长格式,然后按行号和值制表,然后返回并加入以获得所需的输出

agg <- dcast(melt(DT[, rn:=.I], id.vars="rn")[, .N, by=.(rn, value)], 
    rn ~ value, sum, value.var="N")
DT[agg, on=.(rn)]

样本数据:

library(data.table)
set.seed(0L)
DT <- as.data.table(matrix(sample(c(-1L, 0L, 1L, NA_integer_), 5*5e6, replace=TRUE), ncol=5))
DT

编辑:添加了一些时间。 tl;使用data.table 的 500 万行数据集大约需要 10 秒

dtmtd <- function() {
    agg <- dcast(melt(DT[, rn:=.I], id.vars="rn")[, .N, by=.(rn, value)], 
        rn ~ value, sum, value.var="N")
    DT[agg, on=.(rn)]

}    
microbenchmark::microbenchmark(dtmtd(), times=3L)

时间安排:

Unit: seconds
    expr      min       lq     mean  median       uq      max neval
 dtmtd() 10.07663 10.14351 10.17387 10.2104 10.22249 10.23458     3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    相关资源
    最近更新 更多