R dplyr :: Фильтр данных по группам и числам c вектор? - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть фрейм данных df1, содержащий данные и группы, и df2, в котором хранятся те же группы и одно значение на группу.

Я хочу отфильтровать строки df1 по df2, где lag по группам выше указанного значения.

Фиктивный пример:

  # identify the first year of disturbance by lag by group
df1 <- data.frame(year = c(1:4, 1:4),
                 mort = c(5,16,40,4,5,6,10,108),
                 distance = rep(c("a", "b"), each = 4)) 


df2 = data.frame(distance = c("a", "b"),
                       my.median = c(12,1))

Теперь вычислите лаг между значениями (создает новый столбец) и фильтром df1 на основе значений столбца df2:

# calculate lag between years
df1 %>% 
  group_by(distance) %>% 
  dplyr::mutate(yearLag  = mort - lag(mort, default = 0)) %>% 
  filter(yearLag > df2$my.median)  ##

Это, однако, не дает ожидаемых результатов:

# A tibble: 3 x 4
# Groups:   distance [2]
   year  mort distance yearLag
  <int> <dbl> <fct>      <dbl>
1     2    16 a             11
2     3    40 a             24
3     4   108 b             98

Вместо этого я ожидаю получить:

# A tibble: 3 x 4
# Groups:   distance [2]
   year  mort distance yearLag
  <int> <dbl> <fct>      <dbl>
1     3    40 a             24
2     1     5 b              5
3     3    10 b              4

filter прекрасно работает при применении к одному значению, но как адаптировать его к вектору, а особенно к вектору групп (как может потенциально измениться порядок элементов?)

Ответы [ 3 ]

2 голосов
/ 18 февраля 2020

Это то, что вы пытаетесь сделать?

df1 %>% 
  group_by(distance) %>% 
  dplyr::mutate(yearLag  = mort - lag(mort, default = 0)) %>% 
  left_join(df2) %>%
  filter(yearLag > my.median)

Результат:

# A tibble: 4 x 5
# Groups:   distance [2]
   year  mort distance yearLag my.median
  <int> <dbl> <fct>      <dbl>     <dbl>
1     3    40 a             24        12
2     1     5 b              5         1
3     3    10 b              4         1
4     4   108 b             98         1
1 голос
/ 18 февраля 2020

пришли к такому же выводу. Вы должны покинуть фреймы данных.

df1 %>% left_join(df2, by="distance") %>% 
  group_by(distance) %>% 
  dplyr::mutate(yearLag  = mort - lag(mort, default = 0)) %>% 
  filter(yearLag > my.median)

# A tibble: 4 x 5
# Groups:   distance [2]
   year  mort distance my.median yearLag
  <int> <dbl> <fct>        <dbl>   <dbl>
1     3    40 a               12      24
2     1     5 b                1       5
3     3    10 b                1       4
4     4   108 b                1      98
1 голос
/ 18 февраля 2020

здесь data.table подход

library( data.table )
#creatae data.tables 
setDT(df1);setDT(df2)
#create yearLag variable
df1[, yearLag := mort - shift( mort, type = "lag", fill = 0 ), by = .(distance) ]
#update join and filter wanted rows
df1[ df2, median.value := i.my.median, on = .(distance)][ yearLag > median.value, ][]

#    year mort distance yearLag median.value
# 1:    3   40        a      24           12
# 2:    1    5        b       5            1
# 3:    3   10        b       4            1
# 4:    4  108        b      98            1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...