Эффективно сопоставляйте столбцы с несколькими условиями - PullRequest
1 голос
/ 09 апреля 2020

У меня большой фрейм данных, в котором у меня есть два столбца с датами. Для каждого человека (id) date.x содержит уникальную дату, но date.y содержит несколько дат. Я хотел бы сопоставить даты в соответствии с несколькими условиями, чтобы у меня было по одной строке на человека с одним date.x и одним date.y. В порядке предпочтения:

  • , если есть date.y, так что date.x = date.y, тогда я хочу оставить только это date.y.

  • если есть date.y, так что date.x > date.y, то я хочу сохранить только самое близкое значение date.y, которое меньше date.x.

  • , если нет 't date.y, чтобы date.x > date.y (т. е. если все date.y больше date.x), то я хочу сохранить только самое близкое значение date.y, которое больше date.x.

Ниже приведен воспроизводимый пример:

library(tibble)

test <- tibble(
  group = rep(c("A", "B"), each = 6),
  id = rep(rep(1:2, each = 3), 2),
  date.x = rep(c(2002, 2008), each = 6),
  date.y = c(1998, 2000, 2004, 1997, 1998, 1999, 2006, 2008, 2010, 2009, 2010, 2011)
)

# Current form:
# A tibble: 12 x 4
   group    id date.x date.y
   <chr> <int>  <dbl>  <dbl>
 1 A         1   2002   1998
 2 A         1   2002   2000
 3 A         1   2002   2004
 4 A         2   2002   1997
 5 A         2   2002   1998
 6 A         2   2002   1999
 7 B         1   2008   2006
 8 B         1   2008   2008
 9 B         1   2008   2010
10 B         2   2008   2009
11 B         2   2008   2010
12 B         2   2008   2011
# expected output:

# A tibble: 4 x 4
  group    id date.x date.y
  <chr> <int>  <dbl>  <dbl>
1 A         1   2002   2000
2 A         2   2002   1999
3 B         1   2008   2008
4 B         2   2008   2009

Кроме того, поскольку мой фрейм данных довольно большой и иногда делает мой сеанс RStudio cra sh, мне нужно решение, которое является самым экономичным в памяти.

Как я могу это сделать?

Ответы [ 2 ]

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

Вот версия, использующая case_when:

library(dplyr)
test %>%
  group_by(group,id,date.x) %>%
  summarise(date.y = case_when(unique(date.x) %in% date.y ~ unique(date.x), 
                               any(date.y < unique(date.x)) ~ max(date.y[date.y < unique(date.x)]),
                               all(date.y > unique(date.x)) ~ min(date.y)))
## A tibble: 4 x 4
## Groups:   group, id [4]
#  group    id date.x date.y
#  <chr> <int>  <dbl>  <dbl>
#1 A         1   2002   2000
#2 A         2   2002   1999
#3 B         1   2008   2008
#4 B         2   2008   2009
1 голос
/ 09 апреля 2020

Вот возможность.

library(dplyr)

test %>% 
  group_by(id, date.x) %>% 
  filter(
    date.x == date.y |
    date.x - date.y == min(abs(date.x - date.y)) & date.x > date.y |
    date.x + date.y == min(date.x + date.y) & date.x < date.y
  )

# A tibble: 4 x 4
# Groups:   id, date.x [4]
  group    id date.x date.y
  <chr> <int>  <dbl>  <dbl>
1 A         1   2002   2000
2 A         2   2002   1999
3 B         1   2008   2008
4 B         2   2008   2009
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...