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'))
我正在使用 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'))