Проблема с циклами и условными выражениями. Пометка значения как недействительного, когда оно должно быть действительным - PullRequest
0 голосов
/ 10 февраля 2020

У меня возникли некоторые проблемы с условным оператором в функции, над которой я работаю.
Мне нужно оценить, достаточно ли данных в каждом триместре для каждого года и каждой станции мониторинга. Количество данных за первый триместр изменяется, если это високосный год.

Итак, я сделал вложенное l oop для поднабора в год, станцию ​​и триместр, а затем подсчитал количество дней с действительными данными и оценил, было ли оно равным или большим, чем значение ref (то есть действительный триместр ).

Моя проблема в том, что l oop, который я сделал, чтобы решить эту проблему, помечает меня как недействительные некоторые данные, которые должны быть действительными. Я не могу найти причину, почему так я думаю, либо о том, как я сделал oop, либо об условных.

l oop:

X_trim_v<-data.frame()
  for (i in unique(X_max18h$year)){
    for (j in unique(X_max18h$id_station)){
      for (k in unique(X_max18h$trim)){
        X_m18<-subset(X_max18h, year == i & id_station == j & trim == k)
        if (leap_year(i) == T & trim == 1 & length(X_m18$day) >= 67){
            X_trim_v_tmp<-data.frame(year=i,id_station=j,trim=k,n=length(X_m18$day), validez="valido")
            X_trim_v<-rbind(X_trim_v, X_trim_v_tmp)
        } else if (leap_year(i) == F & trim == 1 & length(X_m18$day) >= 68){
            X_trim_v_tmp<-data.frame(year=i, id_station=j, trim=k, n=length(X_m18$day), validez="valido")
            X_trim_v<-rbind(X_trim_v, X_trim_v_tmp)
        } else if (trim == 2 & length(X_m18$day) >= 68){
            X_trim_v_tmp<-data.frame(year=i, id_station=j, trim=k, n=length(X_m18$day), validez="valido")
            X_trim_v<-rbind(X_trim_v, X_trim_v_tmp)
        } else if (trim == 3 | trim == 4 & length(X_m18$day) >= 69){
            X_trim_v_tmp<-data.frame(year=i, id_station=j, trim=k, n=length(X_m18$day), validez="valido")
            X_trim_v<-rbind(X_trim_v, X_trim_v_tmp)
          } else{
            X_trim_v_tmp<-data.frame(year=i, id_station=j, trim=k, n=length(X_m18$day), validez="invalido")
            X_trim_v<-rbind(X_trim_v, X_trim_v_tmp)
          }}}}

Данные, которые должны быть действительными:

year id_station trim  n  validez

2017    TLA     1   68  invalido

2018    CAM     1   68  invalido

2018    NEZ     1   68  invalido

2017    TAH     2   68  invalido

2018    LLA     2   68  invalido

Ответы [ 2 ]

0 голосов
/ 10 февраля 2020

Как подсказал @ A nnet, я использовал dplyr и case_when, чтобы решить это. Я оставляю ответ здесь для будущих ссылок. Я постараюсь прийти позже и сделать лучший пример для тех, у кого такая же проблема.

 X_trim_v<-X_max18h %>%
group_by(year, id_station, trim) %>%
summarise(n=n()) %>%
mutate(validez=case_when((trim == 3 | trim == 4) & n >= 69 ~ "valido",
                         (trim == 1 | trim == 2) & n >= 68 ~ "valido",
                         leap_year(year)== T & trim ==1 & n >= 67 ~ "valido",
                         TRUE ~ "invalido"))
0 голосов
/ 10 февраля 2020

Я думаю, что проблема, с которой вы сталкиваетесь здесь, особенно с l oop, заключается в том, что вы ссылаетесь на подмножество вектора с помощью unique(), а затем вы пытаетесь получить доступ к тем же i, j или k значений, установленных подмножеством l oop, но использующих их для доступа к исходному набору данных.

Не видя, как выглядит полный набор данных, у вас, кажется, есть несоответствие в доступе к данным. Если вы установите условное значение l oop равным for (i in unique(X_max18h$year)){, вы должны будете поддерживать его в соответствии с тем, как вы получите доступ к данным позже для l oop. unique(X_max18h$trim) возвращает только вектор длины "2", поэтому вы будете только l oop дважды, со значением ak 1, а затем, соответственно, 2.

Если вы хотите использовать a для l oop Я бы предложил циклически проходить через каждую строку и проверять условия в каждой строке для вашей встроенной логики c.

for (i in length(X_max18h$trim)) {
    X_m18<-X_max18h[i ,c("year","id_station","trim")] #picking out row i, with selected columns
    if (leap_year(X_m18$year) == T & X_m18$trim == 1 & length(X_m18$day) >= 67){
        X_trim_v_tmp<-data.frame(cbind(X_m18,n=length(X_m18$day)) validez="valido")
        X_trim_v<-rbind(X_trim_v, X_trim_v_tmp)
}

Убедитесь, что вы вводите "X_trim_v = NULL" также в какой-то момент. Код будет ошибочным, как я его написал.

Последний элемент ... если что-то в ваших операторах if или else, если операторы неверны или отсутствуют, ваш код по умолчанию будет соответствовать тому, что говорит ваш последний оператор else. выполнить. Я не вижу столбца под названием "день" в том, как вы инициализируете X_m18, поэтому часть вашего if logi c может вообще не читаться или не учитываться. Поскольку это логика AND c, это может быть причиной вашего крэ sh.

...