Есть ли способ, чтобы не зацикливаться на этом - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть следующий код, который использует месячные данные:

set.seed(2)
vector <- as.data.frame(runif(120)+0.5)
b <- data.frame()

    for (j in 1:I(nrow(vector))) {
        if (is.na(vector[j, i]) || is.na(vector[j + 12, i]) || 
            is.na(vector[j + 24, i]) || is.na(vector[j + 36, i]) ||
            is.na(vector[j + 48, i]) || is.na(vector[j + 60, i])) {
            b[j, i] <- NA
        } else if (vector[j, i] < 1 && vector[j + 12, i] < 1 && 
            vector[j + 24, i] < 1 && vector[j + 36, i] < 1 && 
            vector[j + 48, i] < 1) {
            b[j, i] <- vector[j + 60, i]
        } else {
            b[j, i] <- NA
        }
    }

Сначала проверяется, является ли какое-либо из значений NA (они не будут в этом примере), а затем проверяется, будет ли значение послегод больше, чем один.Есть ли способ, например, использовать dplyr, чтобы получить тот же результат?Проблема в том, что значения находятся на расстоянии двенадцати месяцев друг от друга, но их необходимо проверять каждый месяц.

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Я собираюсь решить вашу проблему с помощью простого вектора вместо data.frame.Об этом легче рассуждать, и он будет легко адаптирован к циклу над столбцами data.frame.

set.seed(2)
v <- runif(120) + 0.5

Вы можете представить «ежемесячность» вектора, изменив его на массив.

w <- matrix(v, nrow = 12)
w[, 1:3]
#            [,1]      [,2]      [,3]
#  [1,] 0.6848823 1.2605133 0.8472722
#  [2,] 1.2023740 0.6808201 0.9887732
#  [3,] 1.0733263 0.9052822 0.6492469
#  [4,] 0.6680519 1.3535485 0.8570626
#  [5,] 1.4438393 1.4763985 1.4626440
#  [6,] 1.4434750 0.7258255 0.6323720
#  [7,] 0.6291590 0.9448092 0.5104145
#  [8,] 1.3334488 0.5749794 0.6646422
#  [9,] 0.9680185 1.1618988 1.3101921
# [10,] 1.0499837 0.8875495 1.3688610
# [11,] 1.0526741 1.3368892 1.0142818
# [12,] 0.7388948 0.6505014 1.1271963

Из вашего кода вы хотите убедиться, что все значения за месяц в течение 5 лет (включая оригинал) меньше 1. Таким образом, мы можем просто сравнить 6 фрагментов матрицы и объединить результаты.

total_cols <- ncol(w)
comparison <- {
  w[, 1:(total_cols - 5)] < 1 &
    w[, 2:(total_cols - 4)] < 1 &
    w[, 3:(total_cols - 3)] < 1 &
    w[, 4:(total_cols - 2)] < 1 &
    w[, 5:(total_cols - 1)] < 1 &
    w[, 6:(total_cols - 0)] < 1
}
comparison
#  [,1]  [,2]  [,3]  [,4]  [,5]
#  [1,] FALSE FALSE FALSE FALSE FALSE
#  [2,] FALSE FALSE FALSE FALSE FALSE
#  [3,] FALSE FALSE FALSE FALSE FALSE
#  [4,] FALSE FALSE FALSE FALSE FALSE
#  [5,] FALSE FALSE FALSE FALSE FALSE
#  [6,] FALSE FALSE FALSE FALSE FALSE
#  [7,]  TRUE  TRUE FALSE FALSE FALSE
#  [8,] FALSE FALSE FALSE FALSE FALSE
#  [9,] FALSE FALSE FALSE FALSE FALSE
# [10,] FALSE FALSE FALSE FALSE FALSE
# [11,] FALSE FALSE FALSE FALSE FALSE
# [12,] FALSE FALSE FALSE FALSE FALSE

Затем мы можем создать новый вектор, используя значения на пять лет вперед, исходя из которых значения comparison равны TRUE.

new_v <- rep(NA, length(v))
new_v[which(comparison)] <- w[, -(1:5)][which(comparison)]
new_v
#   [1]        NA        NA        NA        NA        NA        NA 0.8881448
#   [8]        NA        NA        NA        NA        NA        NA        NA
#  [15]        NA        NA        NA        NA 0.9026427        NA        NA
#  [22]        NA        NA        NA        NA        NA        NA        NA
#  [29]        NA        NA        NA        NA        NA        NA        NA
#  [36]        NA        NA        NA        NA        NA        NA        NA
#  [43]        NA        NA        NA        NA        NA        NA        NA
#  [50]        NA        NA        NA        NA        NA        NA        NA
#  [57]        NA        NA        NA        NA        NA        NA        NA
#  [64]        NA        NA        NA        NA        NA        NA        NA
#  [71]        NA        NA        NA        NA        NA        NA        NA
#  [78]        NA        NA        NA        NA        NA        NA        NA
#  [85]        NA        NA        NA        NA        NA        NA        NA
#  [92]        NA        NA        NA        NA        NA        NA        NA
#  [99]        NA        NA        NA        NA        NA        NA        NA
# [106]        NA        NA        NA        NA        NA        NA        NA
# [113]        NA        NA        NA        NA        NA        NA        NA
0 голосов
/ 26 сентября 2018

Не совсем ясно (для меня), какой вывод вы собираетесь получить, но функция "лидерства" dplyr должна быть в состоянии сделать это, и она также должна сэкономить вам кучу проверок NA.

Если вы просто хотите получить значение на год вперед, с NA, если нет значения на год вперед, это должно быть сделано:

vector <- data.frame(obs = runif(120)+0.5) # giving this variable a name for 
convenience
vector %>% 
  mutate(year_later = lead(obs, 12),
         two_years_later = lead(obs, 24)) # etc

Я помещаю все это в один кадр данных, ноконечно, вы можете оставить свой b <- data.frame(), если хотите.

Это должно повторить ваш первоначальный цикл for, хотя я не получаю никаких наблюдений, которые соответствуют вашим условиям:

vector %>% 
  mutate(final_answer = 
           ifelse(obs < 1 && lead(obs, 12) < 1 && lead(obs, 24) < 1 && lead(obs, 36) < 1 && lead(obs, 48) < 1, 
                  lead(obs, 60), NA))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...