R语言 在半小时上随机选择一个时间,两列之间有一个一小时的缓冲区

8hhllhi2  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(108)

我有一个包含两个不同列的dataframe:
| 结束时间| EndTime |
| --| ------------ |
| 两点| 2:00 |
| 十二点| 12:00 |
| 四点| 4:00 |
| 六点| 6:00 |
| 六点| 6:00 |
我想创建另一个列“SelectedTime”,它是一个随机选择的时间,以半小时为增量(1:00,1:30,2:00,2:30),在StartTime和EndTime之间有一个小时缓冲区。所以第一行是9点到1点之间的随机时间。这可能吗?

qlvxas9a

qlvxas9a1#

如果我们做两个简化的假设--第一,时间是24小时格式的整数,第二,没有一行跨越到第二天--那么下面的假设可能成立。

randTime <- function(DF) {
  # Double each value. This way, we can sample integers and then divide by two
  # to get "on the half-hour" values.
  
  newDF <- DF * 2
  # Next, figure out how many possible half hours choices there are. That should
  # be equal to EndTime - StartTime - 4 where the last 4 is for the hour buffer
  # on either side. Store this in a vector
  validTimes <- newDF$EndTime - newDF$StartTime - 4
  
  # Now pick a random number from 1 to validTimes for each entry
  randHalf <- vapply(validTimes, sample, integer(1L), size = 1L)
  (randHalf + newDF$StartTime) / 2
}

字符串
使用您的初始数据集,我们得到:

DF <- data.frame(StartTime = c(8, 8, 8, 14, 12),
                 EndTime = c(14, 12, 16, 18, 18))
> DF
  StartTime EndTime
1         8      14
2         8      12
3         8      16
4        14      18
5        12      18
set.seed(278L)
> randTime(DF)
[1]  9.0  8.5 10.5 15.0 13.5
> randTime(DF)
[1]  8.5  8.5 12.5 16.0 14.0


将输出格式化为时间或将输入从字符转换的额外步骤应该不会太困难。

g6ll5ycj

g6ll5ycj2#

使用accepted answer from this post

df%>%
  mutate(across(everything(),\(x) as.POSIXct(x, format="%H:%M"))) %>%
  mutate(EndTime=if_else(StartTime>=EndTime, EndTime+ as.difftime(12, units="hours"),EndTime)) %>%
  rowwise()%>%
  mutate(SelectedTime=sample(seq(StartTime+ as.difftime(1, units="hours"),
                                  by=1800,
                                  EndTime-+ as.difftime(1, units="hours")),1)) %>%
  ungroup()

# A tibble: 5 × 3
  StartTime           EndTime             SelectedTime       
  <dttm>              <dttm>              <dttm>             
1 2023-07-20 08:00:00 2023-07-20 14:00:00 2023-07-20 11:00:00
2 2023-07-20 08:00:00 2023-07-20 12:00:00 2023-07-20 11:00:00
3 2023-07-20 08:00:00 2023-07-20 16:00:00 2023-07-20 14:00:00
4 2023-07-20 02:00:00 2023-07-20 06:00:00 2023-07-20 03:00:00
5 2023-07-20 12:00:00 2023-07-20 18:00:00 2023-07-20 16:00:00

字符串
说明:

  • 第一个突变将时间从字符类型转换为POSXct
  • 第二突变解决EndTime小于StartTime的问题(例如,第三行)
  • 使用sample() +seq()以半小时间隔随机采样

相关问题