比r中的ifelse()更快的函数
我有三个栏:旗帜栏、乐谱栏、舞台栏 标志的值为1或0,分数为0以上的任何值。我们需要计算阶段值 因此,我们的数据阶段数据如下所示:比r中的ifelse()更快的函数,r,if-statement,R,If Statement,我有三个栏:旗帜栏、乐谱栏、舞台栏 标志的值为1或0,分数为0以上的任何值。我们需要计算阶段值 因此,我们的数据阶段数据如下所示: Flag Score Stage 1 35 1 0 0 12 .... 如果Flag==1且分数>=30,我们将阶段计算为2 如果Flag==0或Flag==1且分数=30+Flag==0 | Sco
Flag Score Stage
1 35
1 0
0 12
....
如果Flag==1且分数>=30,我们将阶段计算为2
如果Flag==0或Flag==1且分数<30,则stage=1
由于输入错误或分数或标志缺失,任何其他案例阶段将计算为0 ie
stagedata$Stage <- ifelse(stagedata$Flag==1,ifelse((stagedata$Score>=30),2,1),ifelse(stagedata$Flag==0,1,0))
stagedata$Stage[is.na(stagedata$Stage)] <-0
是否有更有效的方法使用其他函数(如apply)来完成此操作?我们正在处理的数据是十位数的我们可以通过一些算术运算将逻辑向量转换成整数
v1 <- with(stagedata, 2 *(Flag == 1 & score >= 30) + (Flag %in% 0:1 & score <30))
v1
#[1] 2 1 1 2 1 0
如果存在NA值,则将其替换为0
v1[is.na(v1)] <- 0
数据
我们可以通过一些算术运算将逻辑向量转换成整数
v1 <- with(stagedata, 2 *(Flag == 1 & score >= 30) + (Flag %in% 0:1 & score <30))
v1
#[1] 2 1 1 2 1 0
如果存在NA值,则将其替换为0
v1[is.na(v1)] <- 0
数据
原始答案和固定答案相差1.07x,而不是1.4x,这不是一个有意义的差别
N <- 10000
set.seed(1)
df <- data.frame(Flag = sample(0:1, N, replace=T), Score = sample(c(12, 35), N, replace=T))
# Flag Score
# 1 0 12
# 2 0 35
# 3 1 35
# 4 1 12
# 5 0 12
# 6 1 12
ifelse_approach <- function() {
df$Stage <- ifelse(df$Flag==1,ifelse((df$Score>=30),2,1),ifelse(df$Flag==0,1,0))
}
lgl_approach <- function() {
df$Stage <- with(df, 2 *(Flag == 1 & Score >= 30) + (Flag %in% 0:1 & Score <30))
}
lgl_fix_approach <- function() {
df$Stage <- with(df, 2 *(Flag == 1 & Score >= 30) + (Flag == 0 | Score < 30))
}
identical(ifelse_approach(), lgl_approach())
# FALSE
identical(ifelse_approach(), lgl_fix_approach())
# TRUE
library(microbenchmark)
microbenchmark(ifelse_approach(), lgl_approach(), lgl_fix_approach(), unit="relative", times=10L)
# Unit: relative
# expr min lq mean median uq max neval
# ifelse_approach() 5.949921 6.048253 5.714637 6.737770 7.186373 3.0478402 10
# lgl_approach() 1.120431 1.111262 1.059140 1.274285 1.376115 0.5364108 10
# lgl_fix_approach() 1.000000 1.000000 1.000000 1.000000 1.000000 1.0000000 10
原始答案和固定答案相差1.07x,而不是1.4x,这不是一个有意义的差别
N <- 10000
set.seed(1)
df <- data.frame(Flag = sample(0:1, N, replace=T), Score = sample(c(12, 35), N, replace=T))
# Flag Score
# 1 0 12
# 2 0 35
# 3 1 35
# 4 1 12
# 5 0 12
# 6 1 12
ifelse_approach <- function() {
df$Stage <- ifelse(df$Flag==1,ifelse((df$Score>=30),2,1),ifelse(df$Flag==0,1,0))
}
lgl_approach <- function() {
df$Stage <- with(df, 2 *(Flag == 1 & Score >= 30) + (Flag %in% 0:1 & Score <30))
}
lgl_fix_approach <- function() {
df$Stage <- with(df, 2 *(Flag == 1 & Score >= 30) + (Flag == 0 | Score < 30))
}
identical(ifelse_approach(), lgl_approach())
# FALSE
identical(ifelse_approach(), lgl_fix_approach())
# TRUE
library(microbenchmark)
microbenchmark(ifelse_approach(), lgl_approach(), lgl_fix_approach(), unit="relative", times=10L)
# Unit: relative
# expr min lq mean median uq max neval
# ifelse_approach() 5.949921 6.048253 5.714637 6.737770 7.186373 3.0478402 10
# lgl_approach() 1.120431 1.111262 1.059140 1.274285 1.376115 0.5364108 10
# lgl_fix_approach() 1.000000 1.000000 1.000000 1.000000 1.000000 1.0000000 10
嗨,阿克伦。看起来棒极了。你知道与ifelse相比,它的计算速度有多快吗?你的解决方案并没有提供与OP相同的结果-更改为withstagedata,2*Flag==1&Score>=30+Flag==0 | Score<30,确实如此-微基准显示它比OP快6倍,比你的计算速度快1.4倍original@CPak即使flag=1,除非分数超过30分,它不会移动到舞台上2@CPak如何获得微基准分数?@akrun-标志只能在c0,1中-如果标志==0==FALSE,则标志必须为1,在这种情况下,只有分数