Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比r中的ifelse()更快的函数_R_If Statement - Fatal编程技术网

比r中的ifelse()更快的函数

比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

我有三个栏:旗帜栏、乐谱栏、舞台栏

标志的值为1或0,分数为0以上的任何值。我们需要计算阶段值

因此,我们的数据阶段数据如下所示:

              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,在这种情况下,只有分数=30+Flag==0 | Score<30,确实如此-微基准显示它比OP快6倍,比你的计算速度快1.4倍original@CPak即使flag=1,除非分数超过30分,它不会移动到舞台上2@CPak如何获取微基准标记分数?@akrun-Flag只能在c0,1中-如果Flag==0==FALSE,则Flag必须为1,在这种情况下,必须只检查score