【发布时间】:2021-02-09 18:29:19
【问题描述】:
我有一个由图书馆借出数据组成的数据集。它记录了签出项目的确切日期和时间。在数据的时间跨度内,新项目进入数据集并首次被检出。这些项目会不时更改其分类。这是我感兴趣的。所以我想做的是获取我的数据集并创建一个新的数据集,记录每周(开始)每个项目的值。
数据
library(dplyr)
# Simulate data
set.seed(1)
item <- rep(1:10, each = 10)
timedate <- as.POSIXct("2010-01-01 00:00:00") + runif(n=100, min=0, max=31*24*60*60)
classification <- sample(c(NA, letters[1:4]), 100, replace = T)
my_df <- tibble(item, timedate, classification) %>%
# Taking a random subset by group
group_nest(item, keep= TRUE) %>%
add_column(mysamples = sample(6:10, 10, replace = T)) %>%
mutate(sampled = map2(data , mysamples, ~ sample_n(.x, .y))) %>%
.$sampled %>%
bind_rows() %>%
arrange(item, timedate)
# This is what my simulated data looks like
my_df
item timedate classification
1 1 2010-01-02 21:58:08 a
2 1 2010-01-07 06:03:04 d
3 1 2010-01-12 12:51:36 c
4 1 2010-01-20 12:03:39 a
5 1 2010-01-21 11:38:00 b
6 1 2010-01-28 20:24:06 <NA>
7 1 2010-01-29 03:42:23 d
8 1 2010-01-30 06:50:18 <NA>
9 2 2010-01-06 11:21:29 a
10 2 2010-01-07 09:14:42 b
11 2 2010-01-12 18:44:46 b
12 2 2010-01-12 21:46:23 b
13 2 2010-01-16 10:17:17 a
14 2 2010-01-22 07:08:41 c
15 2 2010-01-23 05:54:29 a
目标
以前 5 周为例
week <- seq(as.Date("2010-01-01"), as.Date("2010-02-01"), 7)
这些是我认为实现我想要的需要做的说明:
- 选择一周间隔(从第一个开始)
- 对所有项目执行以下操作
- 如果给定项目在间隔期间被签出,则按其所有签出日期对该项目进行排序,然后返回第一个签出日期的类。由于数据集已经记录了一些类为NA,所以这个类可能是字母或NA。
- 如果项目在一周间隔内未签出,请检查该项目之前是否已签出。如果是,则返回最后一个可用的类
- 如果项目在之前的任何时间间隔内都没有被签出,返回“never check out”
- 每隔一周重复一次
总的来说,新数据集应包含length(week)*length(unique(item)) 行。
它将如下所示:
item week classification
1 1 a
1 2 c
1 3 a
1 4 NA
1 5 d
... # looking for the first case where there is no observation in week 1
8 1 "never checked out"
8 2 b
到目前为止我做了什么
到目前为止,我得到的最接近的是使用 lubridate 包中的间隔函数。我已经使用以下函数创建了一些间隔,现在剩下的就是检查在任何特定间隔中项目是否有新分类,如果有,使用它,如果不使用旧分类,如果不存在代码为“从未签出”。
library(lubridate)
myintervals <- map2(head(week, -1), tail(week, -1), function(x,y ) interval(x,y-1))
### Here I just filter out those observations which have multiples of the same date. Not sure if I'm on the right track.
my_df %>%
group_by(item, as.Date(timedate)) %>%
filter(timedate == min(timedate))
请注意,Akruns response 没有使用我的模拟数据,因此不适用于我的情况。
【问题讨论】:
-
你想添加一列'week'吗?
-
是的,这样它会覆盖日期时间,并且分类应该只匹配周间隔内的第一个值。