【问题标题】:Counting Based on 3 Conditions基于 3 个条件的计数
【发布时间】:2018-04-05 13:10:12
【问题描述】:

我有一个数据集,想计算 3 个不同的条件

  1. coinscopay 两列中带有“0”的行数 - 将任一列中的 N/A 计为 0
  2. coins.copay 列 = 1 的行数,但不包括满足条件 1 的值
  3. coins.copay 列 = 0 的行数,但不包括满足条件 1 的值

这是来自更大数据集的样本:

Plan   Year   Coins   Copay   Type   Coins.Copay
 A     2018     0      NA      HMO        1
 B     2018    10      NA      HMO        1
 C     2017    NA       0      SNP        0
 D     2015    20      20      SNP        0
 E     2016    20       0      HMO        1
 F     2018    10      10      HMO        0
 G     2016    NA      NA      HMO        0
 H     2014    NA      NA      HMO        0
 I     2012    NA      10      PPO        0
 J     2011     0       0      HMO        0
 K     2014     5      10      SNP        0
 L     2013    10      NA      HMO        1

因此,我希望有以下计数(基于上述条件):

  1. 5(方案A、C、G、H、J满足条件)
  2. 3(方案B、E、L满足条件;方案A不计入条件1)
  3. 4(计划 D、F、I、K 满足条件;计划 C、G、H、J 不计入满足条件 1)

【问题讨论】:

    标签: r


    【解决方案1】:

    这可以非常有效地使用布尔逻辑来完成:

    zeros_or_na <- (is.na(df$Coins) | !df$Coins) & (is.na(df$Copay) | !df$Copay)
    sum(zeros_or_na)                     # [1] 5
    sum(df$Coins.Copay & !zeros_or_na)   # [1] 3
    sum(!df$Coins.Copay & !zeros_or_na)  # [1] 4
    

    【讨论】:

      【解决方案2】:

      一个选项可以是:

      方法:

      1.在内部条件中使用&amp;,这样决策会很快。

      2.过滤条件2&amp;3 所以过滤器只应用一次。

      3.一旦条件2&amp;3 已使用过滤数据计算,从总行数中减去它们的sum 以获得计数 条件1

      Excluded_conditino_one = which((!is.na(df$Coins) & 
                        df$Coins) | (!is.na(df$Copay) & df$Copay))
      
      
      coins.copay_1 = sum(df[Excluded_conditino_one,"Coins.Copay"]==1) #3
      coins.copay_0 = sum(df[Excluded_conditino_one,"Coins.Copay"]==0) #4
      
      
      Condition_One = length(df$Plan) - (coins.copay_1+coins.copay_0)  #5
      
      
      #Test
      paste(Condition_One, coins.copay_1, coins.copay_0)
      [1] "5 3 4"
      

      工作台性能分析:

      CBarun <- function(df){
        zeros_or_na <- (is.na(df$Coins) | !df$Coins) & (is.na(df$Copay) | !df$Copay)
        Condition_One = sum(zeros_or_na)                     # [1] 5
        coins.copay_1 = sum(df$Coins.Copay & !zeros_or_na)   # [1] 3
        coins.copay_0 = sum(!df$Coins.Copay & !zeros_or_na)  # [1] 4
      }
      
      
      Masoud <- function(df){
        Condition_One = length(which(rowSums(cbind(df$Coins, df$Copay), na.rm=T)==0)) #5
      
        coins.copay_1 = length(which(rowSums(cbind(df$Coins, df$Copay), na.rm=T)!=0 &
        df$Coins.Copay!=0)) #3
      
        coins.copay_0 = length(which(rowSums(cbind(df$Coins, df$Copay), na.rm=T)!=0 &
        df$Coins.Copay==0))   
      }
      
      MKR <- function(df){
      
        Excluded_conditino_one = which((!is.na(df$Coins) &
                df$Coins) | (!is.na(df$Copay) & df$Copay))
      
        coins.copay_1 = sum(df[Excluded_conditino_one,"Coins.Copay"]==1) #3
        coins.copay_0 = sum(df[Excluded_conditino_one,"Coins.Copay"]==0) #4
      
      
        Condition_One = length(df$Plan) - (coins.copay_1+coins.copay_0)  #5
      }
      
      
      library(microbenchmark)
      
      microbenchmark(CBarun(df),
                     #AyushNigam(),
                     Masoud(df),
                     MKR(df),
                     times = 10
      )
      
      # Unit: microseconds
      #       expr     min      lq     mean   median      uq     max neval
      # CBarun(df)  60.790  61.185  71.7644  62.7645  67.896 137.370    10
      # Masoud(df) 185.923 186.317 209.9624 201.3180 222.633 273.949    10
      # MKR(df)    101.054 102.633 122.1330 106.1850 121.975 227.370    10
      

      数据

      df <- read.table(text = 
      "Plan   Year   Coins   Copay   Type   Coins.Copay
      A     2018     0      NA      HMO        1
      B     2018    10      NA      HMO        1
      C     2017    NA       0      SNP        0
      D     2015    20      20      SNP        0
      E     2016    20       0      HMO        1
      F     2018    10      10      HMO        0
      G     2016    NA      NA      HMO        0
      H     2014    NA      NA      HMO        0
      I     2012    NA      10      PPO        0
      J     2011     0       0      HMO        0
      K     2014     5      10      SNP        0
      L     2013    10      NA      HMO        1",
      header = TRUE, stringsAsFactors = FALSE)
      

      【讨论】:

      • 引用:"微秒基准在 R 中毫无意义,因为某些函数在启动它们时会有开销。事实上,某些函数在小型数据集上没有几微秒的开销并不这并不意味着它会在庞大的数据集上进行相同的扩展。换句话说,用户无论如何都感觉不到这种微小的开销,但他们可以在大数据集上感受到几分钟与几秒的开销。因此,基准应该是- 至少以毫秒为单位,如果不是更多的话。”
      【解决方案3】:

      另一种选择是使用lengthrowSums

      length(which(rowSums(cbind(df$Coins, df$Copay), na.rm=T)==0)) #5
      
      length(which(rowSums(cbind(df$Coins, df$Copay), na.rm=T)!=0 & df$Coins.Copay!=0)) #3
      
      length(which(rowSums(cbind(df$Coins, df$Copay), na.rm=T)!=0 & df$Coins.Copay==0)) #4
      

      【讨论】:

      • 我对性能进行了基准测试。看看,如果你想从你的逻辑中调整任何东西,请告诉我。
      • @MKR 我在你的帖子下留下了评论。
      猜你喜欢
      • 2021-05-24
      • 1970-01-01
      • 2023-02-08
      • 2019-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多