R: найти значение> 0 и проверить сумму двух последовательных значений во фрейме данных? - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть датафрейм с двумя столбцами: год и область (целые числа).

df<-data.frame(year = 1:7,
           area = c(5,0,0,8,0,8,4))

  year area
1    1    5
2    2    0
3    3    0
4    4    8
5    5    0
6    6    8
7    7    4

Я хотел бы:

  • Найти первый год с областью> 0
  • Если найден, проверить сумму площадей за два года подряд.Если сумма> 0, выведите год значения.Иначе, (если сумма = 0), ищите следующее число в векторе.

Таким образом, в этом случае год # 1 имеет площадь 5. Но, сумма площади двух следующих лет(# 2 и # 3) равно 0. Поэтому мне нужно проверить новый год в кадре данных с областью> 0, то есть годом # 4.Опять же, я проверяю сумму лет № 5 и № 6, которая равна 8 (> 0).Мой ожидаемый результат - "год 4".


То, что я делал до сих пор:

  • Я могу найти первый год с area >0:

    firstYear<-min(df$year[df$area > 0])
    
  • И вычислите сумму area двух следующих лет:

    sum.year = sum(subset(df, year == firstYear + 1 | year == firstYear + 2)$area)
    

Что я не уверен, так это каквключить операторы if..else или while для перехода к другому year, если сумма двух следующих лет = 0?

Я пытался использовать оператор if..else

if (sum.year >0) {
    print(firstYear)
  } else firstYear = firstYear + 1 # move and check the next year

но я думаю, что мне нужно включить цикл while для перемещения по моим записям:

while (firstYear <= max(df$year)) {
  if (sum.year >0) {
    print(firstYear)
  } else firstYear = firstYear + 1
}

Но я не могу понять, как соединить операторы if..else и while?Спасибо за вашу помощь!

Ответы [ 2 ]

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

Используйте shift, чтобы сложить три значения в одну строку, а затем проверить условие:

library(data.table)
setDT(df)

w = df[, shift(area, 0:2, type="lead")][V1 > 0 & V2 + V3 > 0, which=TRUE][1]

df[w]
#    year area
# 1:    4    8

В базе R, возможно, это аналогично (... я не уверен):

m = embed(df$area, 3)
w = which(m[, 1] > 0 & m[, 2] + m[, 3] > 0)[1]
df[w, ]

#   year area
# 4    4    8
0 голосов
/ 27 сентября 2018

Поскольку вы говорите, что площадь в 6 году равна 8, я предполагаю, что вы агрегируете по годам.По этой логике правильный ответ - год 2 (область 3 года = 0 и область 4 года = 8).Вот код, чтобы сделать это, используя функцию lead из dplyr пакета

library(dplyr)
df <- data.frame(#loc = rep(c("a"),each = 14),
               zone = rep(c("a", "b"), 7),
               year = rep(c(1:7),each= 2),
               area = c(0,1,
                        0,0,
                        0,0,
                        3,5,
                        0,0,
                        1,7,
                        2,2))
x <- group_by(df, year) %>% summarize(area = sum(area))
min(which(lead(x$area, 1, 0) > 0), which(lead(x$area, 2, 0) > 0))
# [1] 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...