Отмечать выбросы повторных мер в пределах группы (если есть тысячи групп) - PullRequest
0 голосов
/ 19 сентября 2019

Я хочу определить искаженные значения из школьного округа.Есть 10 000 школьных округов, и я собрал 14 школьных округов и среднюю сумму, которую они тратят на каждого учащегося в год.Если за предыдущие пять лет значения находятся в диапазоне от 6 до 9000 долларов, то в следующем 2013 году этот школьный округ (и соответствующий ему город) сообщит о расходах на одного учащегося в размере 15000 долларов;по какой-то причине есть хороший шанс, что это значение будет искажено.Есть способы отследить правильное значение, но эта сумма в 15000 долларов, вероятно, искажена и не должна использоваться.

Я создал большой набор данных для анализа расходов на образование (сколько школьный округ тратит на одного учащегося)и уровень преступности, поэтому у меня есть повторяющиеся значения города, округа, школьного округа в течение 14 лет.Я посмотрел на макс / мин для набора данных для школьного округа на расходы ученика (и посмотрел на диаграммы рассеяния), и выявил аномалии.Это заставило меня понять, что могут быть неправильно учтены расходы школьного округа, которые не являются экстремальными для набора данных (хотя они являются экстремальными для данного школьного округа).

Если бы я хотел пометить значения как искаженные на основе стандартного отклоненияЯ мог бы использовать:

flags<-
  dat%>%
    group_by(full_district_id)%>%
    mutate(sd.district_id = sd(EXPENDITURE_PER_STUDENT, na.rm = TRUE),
    flag = ifelse(full_district_id > 2* sd.district_id, "greater",
    ifelse(full_district_id< 2 * sd.district_id, "smaller", "nothing"))%>%
    ungroup()%>%
    filter(flag == "greater"|flag == "smaller")

, но я думаю, что было бы лучше взглянуть на предыдущий год (или что-то вроде пяти предыдущих лет), чтобы увидеть, является ли этот конкретный год аномалией.Таким образом, если значение больше, чем на 4000 долларов больше, чем в любой из предыдущих пяти лет, это значение будет помечено.Я не уверен, как написать условное выражение, которое бы выглядело примерно так: если более 4000 долларов из предыдущих х лет расходов школьного округа, то отметьте это значение.А затем я проверяю эти значения и ищу их правильные значения.

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

Вот небольшой кусок моего набора данных, так что выможете почувствовать, что происходит;хотя для справки, это более 100 000 значений.Большое спасибо!

dput of data

structure(list(year = c(2003, 2005, 2006, 2007, 2008, 2009, 2010, 
2011, 2012, 2013, 2014, 2015, 2016, 2003, 2005, 2006, 2007, 2009, 
2010, 2011), PLACE_ID = c("0100124", "0100124", "0100124", "0100124", 
"0100124", "0100124", "0100124", "0100124", "0100124", "0100124", 
"0100124", "0100124", "0100124", "0100460", "0100460", "0100460", 
"0100460", "0100460", "0100460", "0100460"), CITY = c("abbeville", 
"abbeville", "abbeville", "abbeville", "abbeville", "abbeville", 
"abbeville", "abbeville", "abbeville", "abbeville", "abbeville", 
"abbeville", "abbeville", "adamsville", "adamsville", "adamsville", 
"adamsville", "adamsville", "adamsville", "adamsville"), COUNTY_ID = c("01067", 
"01067", "01067", "01067", "01067", "01067", "01067", "01067", 
"01067", "01067", "01067", "01067", "01067", "01073", "01073", 
"01073", "01073", "01073", "01073", "01073"), full_district_id = c("0101740", 
"0101740", "0101740", "0101740", "0101740", "0101740", "0101740", 
"0101740", "0101740", "0101740", "0101740", "0101740", "0101740", 
"0101920", "0101920", "0101920", "0101920", "0101920", "0101920", 
"0101920"), EXPENDITURE_PER_STUDENT = c(6.91392685629849, 6.80427570954663, 
7.42387732749179, 7.80973129992738, 8.57273726639795, 8.14466546112116, 
7.91766361717101, 7.57727272727273, 7.50594166366583, 7.91607343574372, 
8.26783670354826, 8.4435736677116, 8.48149606299213, 5.93085371942087, 
6.31827864279556, 7.21194954512474, 7.96307522733535, 8.61417039862885, 
9.07166232181485, 8.87169548243168)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -20L))

1 Ответ

0 голосов
/ 20 сентября 2019

Следующее определяет выбросы для каждого district_id и сохраняет строки, в которых расходы на одного учащегося не являются выбросом (определяется для каждого района отдельно):

library(dplyr)
library(outliers)
View(df %>%
      group_by(full_district_id) %>%
       arrange(year)%>% 
        filter(!EXPENDITURE_PER_STUDENT %in% c(outlier(EXPENDITURE_PER_STUDENT))))
...