R 按3个条件计算
我有一个数据集,想计算3个单独的条件R 按3个条件计算,r,R,我有一个数据集,想计算3个单独的条件 两列coins和copay中均为“0”的行数-将任一列中的N/A计算为0 coins.copaycolumn=1但不包括满足条件1的值的行数 coins.copaycolumn=0但不包括满足条件1的值的行数 以下是来自更大数据集的示例: Plan Year Coins Copay Type Coins.Copay A 2018 0 NA HMO 1 B 2018 10
coins
和copay
中均为“0”的行数-将任一列中的N/A计算为0coins.copay
column=1但不包括满足条件1的值的行数coins.copay
column=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
因此,我希望获得以下计数(基于上述条件):
仅使用布尔逻辑即可非常有效地完成此操作:
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
zero_或_na一个选项可以是:
方法:
1.在内部条件下使用&
,以便快速做出决定
2.过滤条件2和3
,因此只应用一次过滤
3.一旦使用过滤数据计算出条件2和3
,从总行计数中减去它们的和
,以获得其计数
条件1
工作台性能分析:
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
CBarun另一个选项是使用length
和rowSums
:
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我在你的帖子下面留下了评论。引用:“微秒基准在R中是没有意义的,因为某些函数在启动时会有开销。某些函数在一个小数据集上没有几微秒的开销这一事实并不意味着它在一个大数据集上也会有同样的开销。换句话说,用户无论如何都感觉不到这种微小的开销,但他们在大数据集上可以感觉到分秒的开销。因此,基准应该至少以毫秒为单位,如果不是更多的话。”
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)
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