Выберите все уникальные записи, показывающие минимум n записей в диапазоне времени - PullRequest
1 голос
/ 17 апреля 2020

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

data= data.frame(Site_ID=c(1, 1, 1, 2, 2, 2, 3, 3, 3), Year=c(1976, 1977, 1978, 2004, 2005, 2006, 2003, 2004, 2005), AnnualMean=c(1.1, 1.2, 1.1, 2.1, 2.6, 3.1, 2.7, 2.6, 1.9))

Я хотел бы выбрать только данные из всех участков мониторинга которые имеют по крайней мере n измерений между годом1 и годом2? Обычно я хотел бы выбрать все данные с сайтов мониторинга, которые показывают 10 измерений в период между 1990 и 2005 годами. До сих пор я пытался безуспешно:

data %>%
group_by(Site_ID) %>%
filter(n()>=n %in% between(Year, year1, year2))

Ответы [ 4 ]

1 голос
/ 17 апреля 2020

Я не уверен, что это ожидаемый результат, возможно, вы можете попробовать

data %>%
  group_by(Site_ID) %>%
  filter(between(Year,1990,2005)) %>%
  filter(Year, n()>=10)

Базовая альтернатива R -

subset(data,
       !!ave(ave(Year,
                 Site_ID,
                 FUN = function(x) x>=1990&x<=2005),
             Site_ID,
             FUN = function(x) sum(x)>2))
1 голос
/ 17 апреля 2020

Выбирает все Site_ID группы, которые содержат не менее parms['n'] наблюдений между parms['yr1'] и parms['yr2'].

library(data.table)
setDT(df)

parms <- c(n = 2, yr1 = 2000, yr2 = 2005)

df[, if(sum(Year %between% parms[c('yr1', 'yr2')]) >= parms['n']) .SD, 
   by = Site_ID]

#    Site_ID Year AnnualMean
# 1:       2 2004        2.1
# 2:       2 2005        2.6
# 3:       2 2006        3.1
# 4:       3 2003        2.7
# 5:       3 2004        2.6
# 6:       3 2005        1.9
1 голос
/ 17 апреля 2020

Этот код в Base-R работает с предоставленными вами образцами данных. Вы можете изменить число в IDstoGet <- Site_IDs[CountBySite_IDs >= 3], чтобы принимать только те идентификаторы Site_ID, у которых больше, чем любое количество точек данных, которые вы хотите.

DataInRange <- data[(data$Year>=1990&data$Year<=2005),]
Site_IDs <- unique(DataInRange$Site_ID)
CountBySite_IDs <- sapply(Site_IDs, function(x) length(grep(x,DataInRange$Site_ID)))
IDstoGet <- Site_IDs[CountBySite_IDs >= 3]
DataToGetPosition <- unlist(lapply(IDstoGet, grep, DataInRange$Site_ID))

DataInRange[DataToGetPosition,]

output

> DataInRange[DataToGetPosition,]
  Site_ID Year AnnualMean
7       3 2003        2.7
8       3 2004        2.6
9       3 2005        1.9
0 голосов
/ 17 апреля 2020

Решение Base R:

# Store a scalar that's values represent the number of observations 
# You would like to filter the data set for: n => numeric vector: 
n <- 10

# Append a site count vector to a subset of the original df: sites_counted_df => data.frame:
sites_counted_df <-
  within(data[which(data$Year >= 1980 & data$Year <= 2005), ],
         {
           count <- ave(Site_ID, Site_ID, FUN = length)
         }
  )

# Filter the data.frame to contain records for sites above "n":
# n_observation_sites => data.frame
n_observation_sites <- sites_counted_df[which(count > n),]

Данные:

data <- data.frame(
  Site_ID = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
  Year = c(1976, 1977, 1978, 2004, 2005, 2006, 2003, 2004, 2005),
  AnnualMean = c(1.1, 1.2, 1.1, 2.1, 2.6, 3.1, 2.7, 2.6, 1.9)
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...