условная фильтрация наблюдений из временных рядов по группам - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть df («df»), содержащий несколько временных рядов (значение ~ время), наблюдения которых сгруппированы по 3 факторам: temp, rep и разновидности.Эти данные необходимо урезать в нижнем и верхнем концах временного ряда, но эти пороговые значения являются условными для группы (например, удалите наблюдения ниже 2 и выше 10, где temp = 10, rep = 2 и разновидности = «A»).У меня есть сопровождающий df (df_thresholds), который содержит значения группирования и минимумы и максимумы, которые я хочу использовать для каждой группы.Не все группы нуждаются в обрезке (я хотел бы регулярно обновлять этот файл, чтобы указать, где обрезать df).Кто-нибудь может мне помочь условно отфильтровать эти значения по группам?У меня есть следующее, которое близко, но не совсем там.Когда я переворачиваю булевы максимальные и минимальные тесты, я получаю ноль наблюдений.

df <- data.frame(species = c(rep("A", 16), rep("B", 16)),
                 temp=as.factor(c(rep(10,4),rep(20,4),rep(10,4),rep(20,4))),
                 rep=as.factor(c(rep(1,8),rep(2,8),rep(1,8),rep(2,8))),
                 time=rep(seq(1:4),4),
                 value=c(1,4,8,16,2,4,9,16,2,4,10,16,2,4,15,16,2,4,6,16,1,4,8,16,1,2,8,16,2,3,4,16))

df_thresholds <- data.frame(species=c("A", "A", "B"), 
                            temp=as.factor(c(10,20,10)),
                            rep=as.factor(c(1,1,2)), 
                            min_value=c(2,4,2),
                            max_value=c(10,10,9))

#desired outcome
df_desired <- df[c(2:3,6:7,9:24,26:27,29:nrow(df)),]


#attempt
df2 <- df

for (i in 1:nrow(df_thresholds)) {  
  df2 <- df2 %>%
    filter(!(species==df_thresholds$species[i] & temp==df_thresholds$temp[i] & rep==df_thresholds$rep[i] & value>df_thresholds$min_value[i] & value<df_thresholds$max_value[i]))
}

РЕДАКТИРОВАТЬ: Вот решение, которое я реализовал согласно предложениям ниже.

df_test <- left_join(df, df_thresholds, by=c('species','temp','rep'))
df_test$min_value[is.na(df_test$min_value)] <- 0
df_test$max_value[is.na(df_test$max_value)] <- 999

df_test2 <- df_test %>%
  filter(value >= min_value & value <= max_value)

1 Ответ

0 голосов
/ 11 декабря 2018

Мы можем узнать индексы, которые мы хотим исключить, используя mapply

df[-c(with(df_thresholds, 
      mapply(function(x, y, z, min_x, max_x) 
           which(df$species == x & df$temp == y & df$rep == z & 
              (df$value < min_x | df$value > max_x)),
                 species, temp, rep, min_value, max_value))), ]


#   species temp rep time value
#2        A   10   1    2     4
#3        A   10   1    3     8
#6        A   20   1    2     4
#7        A   20   1    3     9
#9        A   10   2    1     2
#10       A   10   2    2     4
#11       A   10   2    3    10
#12       A   10   2    4    16
#......

В mapply мы пропустим все столбцы df_thresholds фильтра df соответственно и найдем индексы, которыевне минимального и максимального значения для каждой строки и исключите их из исходного кадра данных.

Результатом вызова mapply будет

#[1]  1  4  5  8 25 28

, то есть строки, которые мы хотим исключить из df, так как они выпадают из диапазона.

...