R 需要提取月份和分配季节

R Need to extract month and assign season

我正在使用 R,我需要设置一个循环(我认为),从中提取月份并分配季节。我想将冬季分配给 12, 1, 2; spring 至 3, 4, 5; 个月,夏季分配给 6, 7, 8; 并分配给 9, 10, 11. 我有以下数据的子集。我对循环很糟糕,无法弄清楚。同样对于日期,我不确定像 lubridate 这样的包是如何工作的

"","UT_TDS_ID_2011.Monitoring.Location.ID","UT_TDS_ID_2011.Activity.Start.Date","UT_TDS_ID_2011.Value","UT_TDS_ID_2011.Season"
"1",4930585,"7/28/2010 0:00",196,""
"2",4933115,"4/21/2011 0:00",402,""
"3",4933115,"7/23/2010 0:00",506,""
"4",4933115,"6/14/2011 0:00",204,""
"8",4933115,"12/3/2010 0:00",556,""
"9",4933157,"11/18/2010 0:00",318,""
"10",4933157,"11/6/2010 0:00",328,""
"11",4933157,"7/23/2010 0:00",290,""
"12",4933157,"6/14/2011 0:00",250,""

仅使用 base R,您可以将“日期时间”列转换为“日期”class (as.Date(..)),提取“月份”(format(..., '%m'))并将字符值更改为数字 (as.numeric()。创建一个值为“1”到“12”的“indx”向量,根据特定季节(setNames(..))设置值的名称,并使用它来获取“月”向量。

 months <- as.numeric(format(as.Date(df$datetime, '%m/%d/%Y'), '%m'))
 indx <- setNames( rep(c('winter', 'spring', 'summer',
                   'fall'),each=3), c(12,1:11))

 df$Season <- unname(indx[as.character(months)])
 df
 #        datetime Season
 #1  7/28/2010 0:00 summer
 #2  4/21/2011 0:00 spring
 #3  7/23/2010 0:00 summer
 #4  6/14/2011 0:00 summer
 #5  12/3/2010 0:00 winter
 #6 11/18/2010 0:00   fall
 #7  11/6/2010 0:00   fall
 #8  7/23/2010 0:00 summer
 #9  6/14/2011 0:00 summer

或者如@Roland 在评论中提到的,您可以使用 strptime 将“datetime”转换为“POSIXlt”并提取月份 ($mon)

 months <- strptime(df$datetime, format='%m/%d/%Y %H:%M')$mon +1

并使用与上述相同的方法

数据

  df <- data.frame(datetime = c('7/28/2010 0:00', '4/21/2011 0:00', 
 '7/23/2010 0:00', '6/14/2011 0:00', '12/3/2010 0:00', '11/18/2010 0:00',
  '11/6/2010 0:00', '7/23/2010 0:00', '6/14/2011 0:00'),stringsAsFactors=FALSE)

关于问题的subject/title,其实不提取月份也是可以的。下面的前两个解决方案不提取月份。还有第三种解决方案,它确实提取了月份,但只是增加了它。

1) as.yearqtr/as.yearmon 将日期转换为 year/month 并添加一个月 (1/12)。然后日历季度对应于季节所以转换为 year/quarter、yq,并如图所示标记季度:

library(zoo)
yq <- as.yearqtr(as.yearmon(DF$dates, "%m/%d/%Y") + 1/12)
DF$Season <- factor(format(yq, "%q"), levels = 1:4, 
                labels = c("winter", "spring", "summer", "fall"))

给予:

       dates Season
1  7/28/2010 summer
2  4/21/2011 spring
3  7/23/2010 summer
4  6/14/2011 summer
5  12/3/2010 winter
6 11/18/2010   fall
7  11/6/2010   fall
8  7/23/2010 summer
9  6/14/2011 summer

1a) 其变体是使用 chron 的 quarters,它会产生一个因子,因此不必指定 levels=1:4。要使用 chron,请将 (1) 中的最后一行替换为:

library(chron)
DF$Season <- factor(quarters(as.chron(yq)), 
                labels = c("winter", "spring", "summer", "fall"))

chron 也可以与其余解决方案结合使用。

2) 切。此解决方案仅使用 R 的基数。首先使用 cut 将日期转换为月份的第一天,然后添加 32 以获得下个月的日期 d。对应于 d 的季度是季节,因此使用 quarters 计算季度并以与第一个答案相同的方式构造标签:

d <- as.Date(cut(as.Date(DF$dates, "%m/%d/%Y"), "month")) + 32
DF$Season <- factor(quarters(d), levels = c("Q1", "Q2", "Q3", "Q4"), 
   labels = c("winter", "spring", "summer", "fall"))

给出相同的答案。

3) POSIXlt 这个解决方案也只使用了 R 的基数:

p <- as.POSIXlt(as.Date(DF$dates, "%m/%d/%Y"))
p$day <- 1
p$mo <- p$mo+1
DF$Season <- factor(quarters(p), levels = c("Q1", "Q2", "Q3", "Q4"), 
               labels = c("winter", "spring", "summer", "fall"))

注 1: 如果我们知道每个季节都会出现,我们可以选择在所有这些解决方案中省略 levels=

注2:我们使用了这个数据框:

DF <- data.frame(dates = c('7/28/2010', '4/21/2011', '7/23/2010', 
 '6/14/2011', '12/3/2010', '11/18/2010', '11/6/2010', '7/23/2010', 
 '6/14/2011'))