Я хочу отфильтровать несколько ошибок данных в огромном (> 20 000 точек) наборе данных.
Вот предполагаемый набор данных (EDIT: я значительно упростил его):
data<-data.table(age=c(1,1,1,2,2,2,3,3,4,4,4,4,4,4),wt=c(32,12,5,32,80,32,1,0,4,8,1,1,2,50))
В этом гипотетическом примере я хочу исключить значения wt
>20 или <6, когда age==1
, затем исключить любые значения wt
+/- 1 SD от среднего за age
2-3 дня, а затем исключить любые значения wt
+/- 2 SD от среднего для age
4.
РЕДАКТИРОВАТЬ
Обратите внимание, что я не пытаюсь сгруппировать возраст 2-3 года, чтобы извлечь 1 среднее значение и 1 стандартное отклонение. Вместо этого я хотел бы dplyr
извлечь среднее значение и стандартное отклонение для каждого возраста (2 и 3) отдельно и применить одни и те же критерии исключения в этом диапазоне возрастов.
Обычно я знаком с dplyr
и думал о том, чтобы решить эту проблему следующим образом (решение, адаптированное из ответа @Suran, которое не сработало так, как нужно):
data_clean<-data%>%filter(
!(age==1 & wt<6),
!(age==1 & wt>20),
!(age==2 & wt >= (mean((data%>%filter(age==2))$wt) +sd((data%>%filter(age==2))$wt))),
!(age==2 & wt <= (mean((data%>%filter(age==2))$wt)-sd((data%>%filter(age==2))$wt))),
!(age==3 & wt >= (mean((data%>%filter(age==3))$wt) +sd((data%>%filter(age==3))$wt))),
!(age==3 & wt <= (mean((data%>%filter(age==3))$wt)-sd((data%>%filter(age==3))$wt))),
!(age==4 & wt >= (mean((data%>%filter(age==4))$wt) +2*sd((data%>%filter(age==4))$wt))),
!(age==4 & wt <= (mean((data%>%filter(age==4))$wt)-2*sd((data%>%filter(age==4))$wt)))
)
Это действительно громоздкое решение, и оно мне не под силу, учитывая, что на самом деле у меня есть 8 различных критериев исключения для разных возрастов. Любые предложения о том, как я могу собрать это вместе?
Обновлено: желаемый окончательный набор данных будет выглядеть так:
age wt
1 12
2 32
2 32
3 1
3 0
4 4
4 8
4 1
4 1
4 2
@SteveM Я обновил свой вопрос, чтобы прояснить ситуацию.
Чтобы получить mean()
для каждого age
, вам нужно сначала group_by(age)
и scale()
перед выполнением аргументов фильтра.
data_clean <- data
group_by(age) %>%
mutate(x = abs(scale(wt)[,1])) %>% #create a new variable that scales the wt, x<=1 means wt is within 1 SD of mean, x<=2 means wt is within 2 SD of mean
ungroup() %>%
filter((age==1 & wt %in% c(6:20) | #keep weights >6g and <20g at age==1
age %in% c(2:3) & x <= 1 | #keep mean wts ± 1 SD for 2-3 days
age>=4 & x<=2) %>% #keep mean wts ± 2 SD for >=4 days
select(-x)
Вы можете использовать несколько каналов фильтрации в своей последовательности фильтрации. Поэтому просто реализуйте свою последовательность фильтров поэтапно для ясности.