【问题标题】:Better & faster way to sum & ifelse for a large set of columns in a big data frame using ddply R使用 ddply R 对大数据框中的大量列进行求和和 ifelse 的更好更快的方法
【发布时间】:2021-09-28 09:50:27
【问题描述】:

问题

我试图按组对数据帧中的每一列求和,如果总和不为 0,则将值设置为 1。我尝试使用 max 函数而不是组合(sum & ifelse),但我一直得到 Inf价值观。但是,该组合需要花费太多时间来计算,我有 150 万行和 500 个虚拟变量要汇总。

有没有更好的方法来实现这一点?

示例数据集

  library(tidyverse)
  library(tibble)
  library(data.table)
  
  rename <- dplyr::rename
  select <- dplyr::select
  
  set.seed(10002)
  id <- sample(1:20, 1000, replace=T)
  
  set.seed(10003)
  group1 <- sample(0:1, 1000, replace=T)
  
  set.seed(10004)
  group2 <- sample(0:1, 1000, replace=T)

  dummies <-
    data.frame(id, group1, group2) 

当前方法

# I am trying to sum each column in a data frame by group and 
# set the value as 1 if the sum is not 0.

  dummies %>% 
    ddply('id', function(x){
      x %>% 
        select_if(is.numeric) %>%
        summarise_each(list(sum)) %>% 
        mutate_if(is.numeric, ~ifelse(.x > 0,1,.x))
    }, .progress = 'text') # It takes too much time 

【问题讨论】:

  • 我认为您可以切换到 dplyr 而不是 dplyr + plyr 即dummies %&gt;% group_by(id) %&gt;% select(where(is.numeric)) %&gt;% dplyr::summarise(across(everything(), ~ +(sum(., na.rm = TRUE) &gt; 0)))

标签: r dplyr plyr


【解决方案1】:

我们可以通过切换到dplyr 来缩短时间。另外,不是先做sum再用ifelse检查再转换,而是直接检查any的值是否大于0

library(dplyr)
dummies %>% 
    dplyr::select(id, where(is.numeric)) %>%
    dplyr::group_by(id) %>% 
    dplyr::summarise(across(everything(), ~ +(any(. > 0, na.rm = TRUE))))

或使用data.table

library(data.table)
setDT(dummies)[, lapply(.SD, function(x)
        +(any(x > 0, na.rm = TRUE))), id, .SDcols = patterns('group')]

【讨论】:

  • 一如既往,@akrun,您的代码运行良好。这是非常快速的计算。非常感谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 2015-02-02
  • 2021-07-04
  • 2017-11-11
  • 2016-08-21
相关资源
最近更新 更多