【问题标题】:Creating an hour range row创建小时范围行
【发布时间】:2017-03-19 22:55:14
【问题描述】:

我目前正在处理来自食品卡车的数据,这些数据由申请人组织、一周中的哪一天开放、开始时间和结束时间。

我被要求制作单独的行或列来描述一个小时是否在开始时间和结束时间的范围内(打开,未打开)。

有没有办法让 R 返回一天中的每个小时,哪些小时在开始时间和结束时间的范围内,并将其标记为打开。然后在不在范围内的每小时询问同一件事并将其标记为未打开。

我尝试使用 for 循环但没有成功。

for(Yes in c("1","2","3","4","5","6","7","8","9","10","11","12","13","14",
             "15","16","17","18","19","20","21","22","23","24"))
{
    print(Yes)
    if(Yes %in% (NSFS$starthour %between% NSFS$endhour))
}



DayOfWeekStr Applicant           starthour  endhour  locationid
Friday       Natan's Catering    12         13       437207
Friday       Linda's Catering    10         15       760539
Wednesday    Mang Hang Catering  12         13       559779
Sunday       Tacos Santana       17         22       453014
Friday       Breaking Bread Inc. 14         18       934995

【问题讨论】:

  • 您能指定结束时间吗?有点被这个问题弄糊涂了
  • 例如,开始时间为 14,结束时间为 22,因此食品卡车的营业时间为下午 2:00 到晚上 10:00。

标签: r time


【解决方案1】:

我假设您有一个 start_hour 和 end_hour 为整数的输入表,例如:

#  applicant    day start_hour end_hour
#1         a monday          9       10
#2         a monday         12       12
#3         a monday         14       16
#4         a monday         17       18

您可以使用seq 查找开始和结束之间的所有时间。以下代码中的想法是生成一个带有开放时间 (dt_open_hours) 的data.table 和一个带有所有可能时间的data.table (dt_all_hours)(使用输入数据中的申请人和天数)。通过合并两个 data.tables,生成的表将包含 applicantdayhour 的所有可能组合,但状态(打开/未打开)将仅来自 dt_open_hours。最后一步是将缺失值 (NA) 转换为“未打开”:

library(data.table)
dt <- structure(list(applicant = structure(c(1L, 1L, 1L, 1L), .Label = "a", class = "factor"), 
  day = structure(c(1L, 1L, 1L, 1L), .Label = "monday", class = "factor"), 
  start_hour = c(9L, 12L, 14L, 17L), end_hour = c(10L, 12L, 
  16L, 18L)), .Names = c("applicant", "day", "start_hour", 
  "end_hour"), class = "data.frame", row.names = c(NA, -4L))

# Convert to data.table
setDT(dt)
# Assign row_id unique row_ids for seq to work on one row at a time
dt[, row_id := seq(1, nrow(dt))]
# Convert start and end hour into sequence of hours between start and end
dt_open_hours <- dt[, .(state = "Open",
                      hour = as.integer(seq(from = start_hour, to = end_hour, by = 1))),
  by = .(row_id, applicant, day)]
# Remove row_id column
dt_open_hours[, row_id := NULL]
# Generate data.table with all combinations of applicant, day and hour
dt_all_hours <- CJ(applicant = unique(dt_open_hours[, applicant]),
                   day = unique(dt_open_hours[, day]), hour = seq(1, 24))
# Merge
out <- dt_open_hours[dt_all_hours, on=.(applicant, day, hour)]
out[is.na(state), state := "Not Open"]

out data.table 如下所示:

#    applicant    day    state hour
# 1:         a monday Not Open    1
# 2:         a monday Not Open    2
# 3:         a monday Not Open    3
# 4:         a monday Not Open    4
# 5:         a monday Not Open    5
# 6:         a monday Not Open    6
# 7:         a monday Not Open    7
# 8:         a monday Not Open    8
# 9:         a monday     Open    9
#10:         a monday     Open   10
#11:         a monday Not Open   11
#12:         a monday     Open   12
#13:         a monday Not Open   13
#14:         a monday     Open   14
#15:         a monday     Open   15
#16:         a monday     Open   16
#17:         a monday     Open   17
#18:         a monday     Open   18
#19:         a monday Not Open   19
#20:         a monday Not Open   20
#21:         a monday Not Open   21
#22:         a monday Not Open   22
#23:         a monday Not Open   23
#24:         a monday Not Open   24
#    applicant    day    state hour

更新:使用以下更新的输入data.frame:

  DayOfWeekStr           Applicant starthour endhour locationid
1       Friday    Natan's Catering        12      13     437207
2       Friday    Linda's Catering        10      15     760539
3    Wednesday  Mang Hang Catering        12      13     559779
4       Sunday       Tacos Santana        17      22     453014
5       Friday Breaking Bread Inc.        14      18     934995

对代码进行了一些修改(除了使用更新后的输入 data.frame 中提供的列名),主要是为了合并locationid 变量:dt_open_hours 包含starthourendhour 之间的小时数对于ApplicantDayOfWeekStrlocationidlocationid 是新的)和dt_all_hours 的每个唯一组合,对于ApplicantDayOfWeekStrlocationid 的相同唯一组合,包含小时 1 到 24 . dt_open_hoursdt_all_hours 的合并是在 ApplicantDayOfWeekStrlocationidhour 上完成的(locationid 是新的)。

library(data.table)
dt <- structure(list(DayOfWeekStr = c("Friday", "Friday", "Wednesday", 
  "Sunday", "Friday"), Applicant = c("Natan's Catering", "Linda's Catering", 
  "Mang Hang Catering", "Tacos Santana", "Breaking Bread Inc."), 
  starthour = c(12L, 10L, 12L, 17L, 14L), endhour = c(13L, 
  15L, 13L, 22L, 18L), locationid = c(437207L, 760539L, 559779L, 
  453014L, 934995L)), .Names = c("DayOfWeekStr", "Applicant", 
  "starthour", "endhour", "locationid"), row.names = c(NA, -5L),
  class = "data.frame")

# Convert to data.table
setDT(dt)
# Assign row_id unique row_ids for seq to work on one row at a time
dt[, row_id := seq(1, nrow(dt))]
# Convert start and end hour into sequence of hours between start and end
dt_open_hours <- dt[, .(state = "Open",
                        hour = as.integer(seq(from = starthour, to = endhour, by = 1))),
                    by = .(row_id, Applicant, DayOfWeekStr, locationid)]
# Remove row_id column
dt_open_hours[, row_id := NULL]
# Generate data.table with all combinations of applicant, day and hour
dt_all_hours <- dt[, .(hour = seq(1, 24)),
                  by = . (Applicant, DayOfWeekStr, locationid)]
# Merge
out <- dt_open_hours[dt_all_hours,
                     on=.(Applicant, DayOfWeekStr, locationid, hour)]
out[is.na(state), state := "Not Open"]

【讨论】:

  • 谢谢,这个例子完美运行!但是,我确实有一个问题。由于我有近 500 个变量,因此手动输入它们并不方便。有没有办法指示 R 遍历每个变量并选择信息?
  • 不客气!请提供输入数据的最小示例(以了解数据的结构)。 500 个变量是否存储在数据框列中?数据是否跨越一周?如果不是,您如何区分数据与例如一周的星期一来自另一周的星期一的数据?
  • 我编辑了我的原始问题以包含一小部分数据输入。我希望这会有所帮助!
猜你喜欢
  • 2017-06-04
  • 2019-06-12
  • 2019-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
相关资源
最近更新 更多