R: более эффективное решение, чем этот цикл for - PullRequest
0 голосов
/ 22 мая 2018

Я написал функционал для цикла, но он медленнее тысяч строк, и я ищу более эффективную альтернативу.Заранее спасибо!

Задача:

  • Если столбец a соответствует столбцу b, столбец d становится NA.
  • Если столбец a не соответствует b, но b соответствует c, тогда столбец e становится NA.

Цикл for:

for (i in 1:nrow(data)) {
     if (data$a[i] == data$b[i]) {data$d[i] <- NA}
     if (!(data$a[i] == data$b[i]) & data$b[i] == data$c[i])
        {data$e[i] <- NA}
}

Пример:

a    b    c    d    e
F    G    G    1    10
F    G    F    5    10
F    F    F    2    8

станет:

a    b    c    d    e
F    G    G    1    NA
F    G    F    5    10
F    F    F    NA    8

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

Мы могли бы создать список предложений и оценить его

library(tidyverse)
qs <- setNames(quos(d*NA^(a == b), e*NA^((!(a ==b) & (b == c)))), c("d", "e"))
df1 %>%
    mutate(!!! qs)
#  a b c  d  e
#1 F G G  1 NA
#2 F G F  5 10
#3 F F F NA  8
0 голосов
/ 22 мая 2018

Предположим, что df - это ваши данные:

ab <- with(df, a==b)
bc <- with(df, b==c)

df$d[ab] <- NA
df$e[!ab & bc] <- NA

, что приведет к

#   a b c  d  e
# 1 F G G  1 NA
# 2 F G F  5 10
# 3 F F F NA  8
0 голосов
/ 22 мая 2018

Если вы беспокоитесь о скорости и эффективности, я бы порекомендовал data.table (хотя технически векторизация нормального data.frame в соответствии с рекомендациями @parfait, вероятно, ускорит процесс более чем достаточно)

library(data.table)

DT <- fread("a    b    c    d    e
             F    G    G    1    10
             F    G    F    5    10
             F    F    F    2    8")
print(DT)
#    a b c d  e
# 1: F G G 1 10
# 2: F G F 5 10
# 3: F F F 2  8

DT[a == b, d := NA]
DT[!a == b & b == c, e := NA]

print(DT)
#    a b c  d  e
# 1: F G G  1 NA
# 2: F G F  5 10
# 3: F F F NA  8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...