我可以创建一个 for 循环来将日历日期划分为 R 中的唯一周吗?

Can I create a for loop to divide calendar dates into unique weeks in R?

我有一个日期列表 (mm/dd/yyyy) 和相关的星期几,其中每个日期代表对事件的观察(见下文)。

Date        DOTW
1/2/2019    Wednesday
1/5/2019    Saturday
1/15/2019   Tuesday
1/17/2019   Thursday
1/22/2019   Tuesday
1/25/2019   Friday
1/25/2019   Friday
2/4/2019    Monday
2/7/2019    Thursday

我想创建以星期日(x 轴)开始的星期几和 y 轴的观察次数(日期在列表中出现的次数)的图。该图将以多行结尾,一行代表日期范围内的每个唯一星期。

我认为我需要创建一个 for 循环来循环周数,但我不确定在不手动创建第三列周数的情况下保持每周分开的最佳方法。

我已经查找了其他类似的帖子(How to divide db dates into weeks?, Convert dates into weeks 等),但没有找到这个特定问题的答案。我还通读了 lubridate 包的功能,但再次不确定它是否能满足这些特定需求。

谢谢!

我知道这不是折线图,但是对于您提供的稀疏数据,折线图在不添加更多列的情况下需要做更多的工作(正如您所说的要避免的那样)。

library(ggplot2)
ggplot(dat, aes(DOTW)) +
  geom_histogram(stat = "count") +
  facet_grid(format(Date, format = "%V") ~ .)
# Warning: Ignoring unknown parameters: binwidth, bins, pad

请参阅下面的数据,了解我如何确保一周中的每一天都正确排序。 我不确定跳过周数是否有问题。 (这是一年中的一周,所以如果您计划有不同的年份,也许多一点会比较合适,例如 format="%Y-%B"。)


数据:

dat <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
Date        DOTW
1/2/2019    Wednesday
1/5/2019    Saturday
1/15/2019   Tuesday
1/17/2019   Thursday
1/22/2019   Tuesday
1/25/2019   Friday
1/25/2019   Friday
2/4/2019    Monday
2/7/2019    Thursday")

dat$Date <- as.Date(dat$Date, format = "%m/%d/%Y")
days <- Sys.Date() + 0:6
dat$DOTW <- factor(dat$DOTW, levels = format(days, format = "%A")[order(format(days, format = "%w"))])

如果任何数据发生在星期日,该图将从星期日开始。 如果您更喜欢基于星期一的周,请将 "%w" 替换为 "%u"。另一个顺便说一句:如果任何 DOTW 值的拼写完全不同,它将被替换为 NA。如果您在绘图中看到异常行为,请查找这些值,如果找到,您可能需要研究适应这些细微差异的方法,以保持工作日顺序。

不确定这是否是您想要的...

编了一堆数据,因为您提供的样本会使解释折线图变得相当困难,而这正是您所要求的。

library(lubridate)
library(dplyr)
library(ggplot2)


set.seed(123)

day_start <- "2019/01/01"
day_end <- "2019/01/31"

day_seq <- seq(as.Date(day_start), as.Date(day_end), by = "day")

df <-  
  data.frame(Date = sample(day_seq, 500, replace = TRUE)) %>% 
  mutate(Wk = week(Date),
         Dy = wday(Date, label = TRUE,  week_start = getOption("lubridate.week.start", 7))) %>% 
  group_by(Wk, Dy) %>% 
  summarise(Count = n())

ggplot(df, aes(Dy, Count, group = factor(Wk), colour = factor(Wk)))+
  geom_line()

reprex package (v0.3.0)

于 2020-05-17 创建

还不完全清楚您真正想要的是什么,但我已经给出了一些示例数据:

library(lubridate)
library(dplyr)
library(ggplot2)
# Create reprex-data
Date <- seq(as.Date("2020-01-01"),as.Date("2020-03-15"), by = "days"),
Sys.setlocale("LC_TIME", "English")
DOTW <- factor(weekdays(Date), levels = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), labels = c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"))
Weeknum <- week(Date)
df <- data.frame(Date, DOTW, Weeknum)
df1 <- sample_n(df, size = 800, replace = T)


df_plot <- df1 %>%
  group_by(Weeknum, DOTW) %>%
  summarise(count = n())

df1 %>%
  group_by(Weeknum, DOTW) %>%
  summarise(count = n()) %>%
  filter(Weeknum <= 5) %>%
ggplot()+
  geom_line(aes(x = DOTW, y = count, group = Weeknum, colour = Weeknum))

我在这里对数据进行了分组和汇总,以便计算每个日期在给定周内每个工作日出现的次数。最后,绘制了它(为了便于阅读,我在这里将其过滤为 5 周)。

但是,这不是图形化的好解决方案。考虑改用条形图,并使用 facet_wrap 分隔周数 - 示例:

df1 %>%
  group_by(Weeknum, DOTW) %>%
  summarise(count = n()) %>%
ggplot(aes(x = DOTW, y = count, fill = DOTW))+
  geom_col()+
  facet_wrap(~ Weeknum)+
  theme(axis.text.x = element_text(angle = 45), legend.position = "none")