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

时间:2015-01-19 18:06:19

标签: r date

我正在使用R,我需要设置一个循环(我认为),我从日期中提取月份并指定一个季节。我想将冬季分配到12, 1, 2;夏季到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,""

2 个答案:

答案 0 :(得分:5)

关于问题的主题/标题,实际上可以在不提取月份的情况下执行此操作。下面的前两个解决方案不提取月份。还有第三个解决方案确实提取月份,但只是增加它。

1)as.yearqtr / as.yearmon 将日期转换为年/月并添加一个月(1/12)。然后,日历季度对应于季节,因此转换为年份/季度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'))

答案 1 :(得分:1)

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

 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转换&#34;日期时间&#34; to&#34; POSIXlt&#34;并提取月份($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)