странная проблема R — значения в переменной пропадают после цикла if

#r #loops #variables #if-statement

#r #циклы #переменные #if-оператор

Вопрос:

У меня довольно странная проблема — после того, как я вычисляю некоторые даты (хранящиеся в переменной ‘datumi’), и если я запускаю ее, как в первом случае ниже, я получаю сообщение об ошибке, говорящее о том, что в последнем цикле if отсутствует значение (ошибка в if ({ : отсутствующее значение, где требуется TRUE / FALSE).

фрейм данных d (который я бы предпочел загрузить в виде файла .csv, но я не вижу этой опции):

 d = 
1  2012-09-16  0.84 19.625243     FALSE   19.62524
2  2012-09-17  0.84 33.327431     FALSE   52.95267
3  2012-09-18  0.84 62.887769     FALSE  115.84044
4  2012-09-19  0.84 28.452394     FALSE  144.29284
5  2012-09-20  0.84 70.913258     FALSE  215.20610
6  2012-09-21  0.84 40.573884     FALSE  255.77998
7  2012-09-22  0.84 66.525374      TRUE  322.30535
8  2012-09-27  0.97 54.060930      TRUE  376.36628
9  2012-12-11  0.94 59.708620      TRUE  436.07490
10 2013-02-18  0.84 61.645767     FALSE  497.72067
11 2013-02-19  0.84 24.086509      TRUE  521.80718
12 2013-02-27  0.94 58.148436     FALSE  579.95562
13 2013-02-28  0.94  6.884530     FALSE  586.84015
14 2013-03-01  0.94 18.269344     FALSE  605.10949
15 2013-03-03  0.94 24.968575     FALSE  630.07807
16 2013-03-04  0.94 29.888434     FALSE  659.96650
17 2013-03-05  0.94 70.158147     FALSE  730.12465
18 2013-03-06  0.94 67.772256     FALSE  797.89690
19 2013-03-07  0.94 74.875140     FALSE  872.77204
20 2013-03-08  0.94 10.682086     FALSE  883.45413
21 2013-03-10  0.94 83.325472     FALSE  966.77960
22 2013-03-11  0.94 61.428804     FALSE 1028.20840
23 2013-03-12  0.94 90.050368     FALSE 1118.25877
24 2013-03-13  0.94 57.943451     FALSE 1176.20222
25 2013-03-14  0.94 29.740228     FALSE 1205.94245
26 2013-03-15  0.94  6.786190     FALSE 1212.72864
27 2013-03-17  0.94 64.275445     FALSE 1277.00409
28 2013-03-18  0.94 14.502550     FALSE 1291.50664
29 2013-03-19  0.94 60.892779     FALSE 1352.39942
30 2013-03-20  0.94 31.152046     FALSE 1383.55146
31 2013-03-21  0.94 40.834755     FALSE 1424.38622
32 2013-03-22  0.94 13.317670     FALSE 1437.70389
33 2013-03-24  0.94 54.218275     FALSE 1491.92216
34 2013-03-25  0.94 10.910257     FALSE 1502.83242
35 2013-03-26  0.94  5.688037     FALSE 1508.52046
36 2013-03-27  0.94 27.859595     FALSE 1536.38005
37 2013-03-28  0.94 32.144926     FALSE 1568.52498
38 2013-03-29  0.94 42.197229      TRUE 1610.72221
39 2013-04-01  0.84  1.973316     FALSE 1612.69552
40 2013-04-02  0.84 70.191520     FALSE 1682.88704
41 2013-04-03  0.84 47.700082     FALSE 1730.58712
42 2013-04-04  0.84 65.108000     FALSE 1795.69512
43 2013-04-05  0.84 65.686734     FALSE 1861.38186
44 2013-04-07  0.84 82.046046     FALSE 1943.42790
45 2013-04-08  0.84 28.383566     FALSE 1971.81147
46 2013-04-09  0.84  8.957643     FALSE 1980.76911
47 2013-04-10  0.84 56.305904     FALSE 2037.07502
48 2013-04-11  0.84 32.909041     FALSE 2069.98406
49 2013-04-12  0.84 81.166025     FALSE 2151.15008
50 2013-04-14  0.84 58.212950     FALSE 2209.36303
  

Код:

 l = 2
spr <- matrix(,,5)
datumi <- c()
datumi[1] <- as.character(as.Date("2012-07-24", format = "%Y-%m-%d"))
spr[1,2] <- 0
spr[1,5] <- 0
for(j in 1:nrow(d)){
    if(d[j,4] == TRUE){
        spr <- rbind(spr,NA)
        datumi[l] <- if(j < nrow(d)){
            as.character(as.Date(d[{j 1},1], format = "%Y-%m-%d"))  
            } else {
            as.character(as.Date("2014-01-15", format = "%Y-%m-%d"))
            }
        spr[l,1] <- difftime(datumi[l],datumi[l-1],units="days")  
        if(spr[l,1] == 0){
            spr[l,1] <- 1
        }
        spr[l,2] <- d[j,5] - spr[{l-1},5]  
        spr[l,3] <- spr[l,2] / spr[l,1]  
        spr[l,4] <- as.numeric(as.character(d[j,2]))  
        spr[l,5] <- d[j,5]
        l = l 1
    } 

datumi <- as.Date(datumi)

days <- seq(from=as.Date("2012-07-24"), to=as.Date("2014-01-15"),by='days')


freq <- c()
  for(j in i:length(days)){
    for(k in 2:length(datumi)){
        if({datumi[k-1] <= days[j]} amp;amp; {days[j] < datumi[k]}){
            freq[j] <- spr[k,3]
        }
    }
}
  

Результатом теперь является вышеупомянутая ошибка:

(Ошибка в if ({ : отсутствует значение, где требуется TRUE / FALSE)

Что происходит потому, что ‘datumi’ выглядит так:

данные [1] «2012-07-24»

вместо этого, как это правильно:

datumi [1] «2012-07-24» «2013-10-03» «2013-12-13» «2013-12-13» «2013-12-14» «2013-12-15» «2014-01-15»

Но интересная вещь происходит, когда я запускаю обе части кода по отдельности:

 l = 2
spr <- matrix(,,5)
datumi <- c()
datumi[1] <- as.character(as.Date("2012-07-24", format = "%Y-%m-%d"))
spr[1,2] <- 0
spr[1,5] <- 0
for(j in 1:nrow(d)){
    if(d[j,4] == TRUE){
        spr <- rbind(spr,NA)
        datumi[l] <- if(j < nrow(d)){
            as.character(as.Date(d[{j 1},1], format = "%Y-%m-%d"))  
            } else {
            as.character(as.Date("2014-01-15", format = "%Y-%m-%d"))
            }
        spr[l,1] <- difftime(datumi[l],datumi[l-1],units="days")  
        if(spr[l,1] == 0){
            spr[l,1] <- 1
        }
        spr[l,2] <- d[j,5] - spr[{l-1},5] 
        spr[l,3] <- spr[l,2] / spr[l,1]  
        spr[l,4] <- as.numeric(as.character(d[j,2]))  
        spr[l,5] <- d[j,5]
        l = l 1
    } 

datumi <- as.Date(datumi)
  

И затем

 days <- seq(from=as.Date("2012-07-24"), to=as.Date("2014-01-15"),by='days')


freq <- c()
  for(j in i:length(days)){
    for(k in 2:length(datumi)){
        if({datumi[k-1] <= days[j]} amp;amp; {days[j] < datumi[k]}){
            freq[j] <- spr[k,3]
        }
    }
}
  

Я получаю вектор частот в переменной ‘freq’. Результат в ‘datumi’ теперь правильный:

datumi [1] «2012-07-24» «2012-09-27» «2012-12-11» «2013-02-18» «2013-02-27» [6] «2013-04-01»

Итак, кажется, что каким-то образом значения (все, кроме первого) в переменной ‘datumi’ стираются, когда я запускаю ее в цикле if, но я не могу понять, почему это происходит, только если я запускаю обе части кода вместе (1-й случай), а не если я запускаю их одну за другой (второй случай).

У кого-нибудь есть идеи, как это исправить?

Комментарии:

1. Я думаю, у вас есть нижний индекс вне длины вектора в одном из if операторов. Невозможно понять, как это написано, но проверьте, что ваши индексы всегда находятся между 1 и длиной каждого вектора.

2. Можете ли вы предоставить нам матрицу d , чтобы мы могли выполнить приведенный выше код? Трудно понять, что может быть не так, без воспроизводимого примера.

Ответ №1:

В вашем объединенном коде, на вашей первой итерации, ваша переменная datumi имеет длину 1, которую вы можете увидеть, поместив print(datumi) где-нибудь перед концом первой части кода. Однако ваш второй цикл начинается с 2 и затем переходит к 1. Смотрите часть for(k in 2:length(datumi)){ . Здесь говорится: для k in 2 then 1 выполните if({datumi[k-1] <= days[j]} amp;amp; ... . Следовательно, на первой итерации осуществляется доступ к datum[2-1] , а на второй итерации осуществляется доступ к datumi[0] , который не существует.

С другой стороны, когда вы выполняете коды по отдельности, первая часть вашего кода возвращается datumi в виде вектора длиной 6 и k не принимает значение 1 , а переходит от 2 к 3 to … до 6. Вот почему вторая часть вашего кода работает, когда вы выполняете их по отдельности.

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

Комментарии:

1. Большое вам спасибо за ваш ответ! Вчера я часами искал решение, и теперь я нашел его с вашей помощью (и я должен признать, что чувствую себя немного глупо) — мне просто пришлось добавить дополнительный ‘}’ в предпоследнюю строку в первой части кода. Это произошло потому, что у меня был другой цикл for, и я забыл завершить его. Ну, я предполагаю, что виноват недостаток опыта плюс тот факт, что RStudio не работает на моем компьютере, и мне приходится все делать вручную.