Убрать наблюдение перед определенным рядом - PullRequest
1 голос
/ 07 февраля 2020

У меня есть фрейм данных, и я хочу вычислить среднее значение по переменной value для всего периода, за исключением + - два наблюдения до / после этого кризиса 1 (мне все равно, что пропущено значение val) , Расчет должен быть сделан по стране (хотя здесь, в примере ниже, у меня есть только одна страна). Пример:

country <- rep("AT",10)
value <- seq(1,10,1)
crisis <- c(0,0,0,NA,0,1,0,NA,0,0)

df <- data.frame(country, value, crisis)
df


mean(df$value[df$crisis == 0], na.rm=TRUE)

# expected result

exp_mean <- (1+2+3+9+10)/5
exp_mean

edit:

Я хотел бы получить общий случай, когда мы принимаем во внимание другие возможные 1 в наборе данных, например, если у нас есть

crisis[10] = 1, результат должен быть (3+9)/2

, чтобы не учитывать периоды после первого кризиса, но которые фактически переживают кризис во втором периоде. Есть идеи?

Ответы [ 3 ]

3 голосов
/ 07 февраля 2020

Другое базовое решение R, использующее outer + c + unique для фильтрации строк, т. Е.

r <- mean(na.omit(df[-unique(c(outer(which(df$crisis==1),-2:2,"+"))),"value"]))

, такое что

> r
[1] 5
2 голосов
/ 07 февраля 2020

Мы можем написать функцию, которая исключает переменные, которые представляют собой + - 2 наблюдения после использования crisis = 1.

custom_mean <- function(c, v) {
   inds <- which(c == 1)
   mean(v[-unique(c(sapply(inds, `+`, -2:2)))], na.rm = TRUE)
}

sapply при условии, что для страны может быть несколько crisis = 1 ситуаций.

Затем мы можем применить эту функцию для каждого country.

library(dplyr)
df %>% group_by(country) %>% summarise(exp_mean = custom_mean(crisis, value))

# A tibble: 1 x 2
#  country exp_mean
#  <fct>      <dbl>
#1 AT             5
1 голос
/ 07 февраля 2020

Это решение, использующее базу R, работает до тех пор, пока есть только одно значение с «кризисом == 1», и до тех пор, пока всегда есть две строки до и после строки с «кризисом == 1»

country <- rep("AT",10)
value <- seq(1,10,1)
crisis <- c(0,0,0,NA,0,1,0,NA,0,0)

df <- data.frame(country, value, crisis)
df

df[(which(df$crisis == 1) - 2):(which(df$crisis == 1) + 2), ]

Это решение не работает для этих данных:

country <- rep("AT",11)
value <- seq(1,11,1)
crisis <- c(0,0,0,NA,0,1,0,NA,0,0,1)

df2 <- data.frame(country, value, crisis)


df2[(which(df2$crisis == 1) - 2):(which(df2$crisis == 1) + 2), ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...