Быстрее, чем ifelse () в r - PullRequest
       5

Быстрее, чем ifelse () в r

0 голосов
/ 25 апреля 2018

У меня есть 3 столбца Флаг, Оценка, Сцена .

Флаг будет иметь значения 1 или 0, Оценка будет иметь любые значения выше 0. Нам нужно рассчитать значения этапа.

поэтому наши данные (stagedata) будут выглядеть следующим образом:

              Flag Score Stage
               1    35
               1    0
               0    12
               ....

IF Flag == 1 и счет> = 30, мы вычисляем этап как 2,

, и еслиФлаг == 0 или Флаг == 1 и оценка <30, стадия = 1. </p>

Любая другая стадия случая будет рассчитываться как 0 (т. Е. Из-за некоторой ошибки при вводе или если оценка или флаг отсутствуют),

        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?Данные, с которыми мы имеем дело, имеют порядок десяти тысяч

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Исходный и фиксированный ответ различаются на 1,07, а не в 1,4 раза, - не имеет существенного значения.

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
0 голосов
/ 25 апреля 2018

Мы можем преобразовать логический вектор в целое число с помощью некоторой арифметической операции

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

данные

stagedata <- data.frame(Flag = c(1, 1, 0, 1, 0, 2), score = c(35, 0, 12, 31, 27, 31))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...