使用dplyr,按id和日期分组数据,查找第一个和最后一个位置

5tmbdcev  于 2023-02-06  发布在  其他
关注(0)|答案(3)|浏览(129)

编辑:抱歉,我的示例数据看起来太简单/漂亮了。完整的数据集要大得多。我无法通过按日期或其他方式排序来恢复事件的顺序。而且on和off是id,而不是事件编号,所以也没有顺序。我更新了示例以更好地反映这一点。
以下是一些示例数据:

ids <- c(1, 1, 1, 2, 2, 2)
date <- c(1,1,1, 3,3,3)
off <- c(234,234,93, 675,876,876) # these are ids
on <- c(93,111,234, 876,675,675) # these are ids

df <- data.frame(ids, dates, on, off)

这表示行程,即个体1从234 -〉93 -〉234 -〉111个体2从876 -〉675 -〉876 -〉675
日期信息不够详细,不能自己订购记录,我不能只取第一个和最后一个。
按ID和日期对数据进行分组,我希望确定第一个关闭位置和最后一个打开位置,并将其聚合到一条记录中。
我希望在这种情况下

ids <- c(1, 2)
date <- c(1,3)
off <- c(234, 111)
on <- c(876, 675)

我试过很多方法,但没有一种是有效的。

mqkwyuun

mqkwyuun1#

看起来您的逻辑是,对于每个id,您只需要off的最小值和on的最大值,因此这应该可以做到。

library(dplyr, warn.conflicts = FALSE)
ids <- c(1, 1, 1, 2, 2, 2)
date <- c(1,1,1, 3,3,3)
off <- c(111,234,111, 675,876,675)
on <- c(234,111,876, 876,675,876)

df <- data.frame(ids = ids, date = date, on = on, off = off)
df %>%
  group_by(ids) %>%
  filter(on == max(on), off == min(off)) %>%
  distinct()
#> # A tibble: 2 × 4
#> # Groups:   ids [2]
#>     ids  date    on   off
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1     1   876   111
#> 2     2     3   876   675

reprex package(v2.0.1)于2023年2月2日创建

evrscar2

evrscar22#

也可以使用group_byslice_head

data.frame(ids, date, on, off) %>% arrange(ids,date, on, off) %>% group_by(ids) %>% 
slice_head(n=1)

创建于2023年2月2日,使用reprex v2.0.2

# A tibble: 2 × 4
# Groups:   ids [2]
    ids  date    on   off
  <dbl> <dbl> <dbl> <dbl>
1     1     1   111   234
2     2     3   675   876
7lrncoxx

7lrncoxx3#

每个组的首行和末行决定了开始和结束。因此,选择它们并汇总数据。例如:

library(dplyr)
library(tidyr)

df %>% 
  group_by(ids, date) %>% 
  mutate(start = case_when(row_number() == 1 ~ off),
         end = case_when(row_number() == n() ~ on)) %>% 
  select(-on, -off) %>% 
  filter(!(is.na(start) & is.na(end))) %>% 
  fill(start, .direction="down") %>% 
  fill(end, .direction="up") %>% 
  distinct()

这将导致:

# A tibble: 2 × 4
# Groups:   ids, date [2]
    ids  date start   end
  <dbl> <dbl> <dbl> <dbl>
1     1     1   111   876
2     2     3   675   876

相关问题