我正在使用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,""
答案 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)