R 使用仅包含ISO周的数据集将ISO周聚合为月

R 使用仅包含ISO周的数据集将ISO周聚合为月,r,date,R,Date,我的数据位于数据框中,其结构如下: df2 <- data.frame(Year = c("2007"), Week = c(1:12), Measurement = c(rnorm(12, mean = 4, sd = 1))) df2这可以在dplyr中相对简单地完成 library(dplyr) df2 %>% mutate(Month = rep(1:3, each = 4)) %>% group_by(Month) %>% summaris

我的数据位于数据框中,其结构如下:

df2 <- data.frame(Year = c("2007"), Week = c(1:12), Measurement = c(rnorm(12, mean = 4, sd = 1)))

df2这可以在dplyr中相对简单地完成

library(dplyr)

df2 %>% 
  mutate(Month = rep(1:3, each = 4)) %>% 
  group_by(Month) %>% 
  summarise(MonthlyMedian = stats::median(Measurement))
基本上,添加一个新列来定义月份。我想既然你没有天数,你每个月会分配4周? 然后,您只需按月份变量分组并计算中位数。很简单


希望这对您有所帮助

使用
dplyr
您可以尝试:

require(dplyr)

df2 %>% mutate(Date = as.Date(paste("1", Week, Year, sep = "-"), format = "%w-%W-%Y"),
            Year_Mon = format(Date,"%Y-%m")) %>% group_by(Year_Mon) %>%
            summarise(result = median(Measurement))

正如@djhrio所指出的,星期四用来确定一个月中的几周。因此,只需将上面代码中的粘贴(“1”)切换到粘贴(“4”)即可。

如果我理解正确,您不知道确切的日期,只知道周数和年份。我的答案以一年中的第一天为开始日期,然后在此基础上计算一周的间隔。您可能可以改进答案

基于 ,使用

库(lubridate)
#为合并准备周、月、年信息
#确保你有所有必要的日期
WMY 

当有必要分配一个星期到一个月时,适用于一年的第一周的规则,尽管ISO 8601不考虑这种情况。 例如,2007年的第5周属于2月,因为第5周的星期四是2月1日

我正在使用
data.table
ISOweek
包。请参见如何计算一周中的月份的示例。然后您可以按月进行任何聚合

require(data.table)
require(ISOweek)

df2 <- data.table(Year = c("2007"), Week = c(1:12),
                  Measurement = c(rnorm(12, mean = 4, sd = 1)))

# Generate Thursday as year, week of the year, day of week according to ISO 8601
df2[, thursday_ISO := paste(Year, sprintf("W%02d", Week), 4, sep = "-")]

# Convert Thursday to date format
df2[, thursday_date := ISOweek2date(thursday_ISO)]

# Compute month
df2[, month := format(thursday_date, "%m")]
df2
最后,您可以对新表进行聚合,或者将中位数添加为列

df2[, median(Measurement), by = yr_mon]

df2[, median := median(Measurement), by = yr_mon]
df2

这是有问题的,因为2007年的第5周仍然是在1月。@count,实际上2007年的第5周是在2月,因为一周中的月份是根据ISO标准定义的一周中的星期四定义的。2007-W05的星期四是2007-02-01。@djhrio很有趣,不知道这一点。不过,简单地每月分配4周可能是有限制的若要在本场景中产生不准确的情况,您将如何调用您刚通过简单方法创建的13.月份?:-)如果您每月分配4周,每年有52或53周,您将结束13个4周的周期(加上1或2天)。这太简单了,IMHO。@Uwe,这个例子包含了12周,没有迹象表明它是否超过了一年,因此超级简化谢谢,这对我来说很有效!我选择了你的答案,因为它更适合在我的数据中的其他年份的后续实施。把每个星期四的月份作为一个好主意。这可以确保将整个星期分配给一周中大部分天数所属的月份。但是,为了安全起见,我建议创建一个年-月字符串并简化代码,即,
yru_mon:=格式(isoweekDate(sprintf(“%I-W%02i-4”,year,week)))
。刚刚注意到您没有使用聚合部分。因此,完整的答案应该是
库(data.table);setDT(df2)[,median(Measurement),by=(Yr_Mon=格式(ISOweek::ISOweek2date(sprintf(“%s-W%02d-4”,Year,Week)),“%Y-%m”)]
@Uwe,谢谢!刚刚注意到你是
ISOweek
的作者。非常感谢你的软件包!很抱歉我花了这么长时间才接受这个答案。感谢你的一千次解释!!感谢你的详细回答!它工作得非常好,但我选择接受另一个答案,因为它为
提供了更多的灵活性>稍后在我的代码中包含ISOweek
包。请注意,基于ISO周的年份可能与日历年不同。例如,
ISOweek::ISOweek(“2010-01-01”)
返回“2009-W53”,
ISOweek::ISOweek(“2011-01-01”)
“2010-W52”。请参阅
?strtime
中的
%G
%G
。中讨论了确定一年中一周的不同约定。@Uwe谢谢。我明白了,
lubridate::isoweek(“2010-01-01”)
返回
53
lubridate::year(“2010-01-01”)
返回
2010
。我应该使用
lubridate::isoyear(“2010-01-01”)
返回
2009
。OP指出他使用的是ISO周。因此,答案使用了英国对一年中的一周的定义
%W
以及从周日开始的工作日编号
%W
(ISO周从周一开始)显然是错误的(请参见
?strtime
)。还请注意,属于ISO周的年份可能与日历年不同。请参阅,以了解不同约定的讨论。小心。此解决方案适用于2007年,但不适用于2008年以及1月1日为Tu、We或Th的其他年份,因为按
%W
对周进行编号不符合ISO标准。从
strtime
帮助中:“%W:一年中的一周作为十进制数(00–53),使用星期一作为一周的第一天(通常将一年中的第一个星期一作为第一周的第一天)。@Uwe和djurio我不知道。感谢您的输入!
# Compute year-month
df2[, yr_mon := format(ISOweek2date(sprintf("%s-W%02d-4", Year, Week)), "%Y-%m")]
df2
df2[, median(Measurement), by = yr_mon]

df2[, median := median(Measurement), by = yr_mon]
df2