【问题标题】:R Need to extract month and assign season [duplicate]R需要提取月份并分配季节[重复]
【发布时间】:2015-01-19 18:06:19
【问题描述】:

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

【问题讨论】:

  • 与“季节”一词混淆。可能修改标题以将“季节”替换为“季度”以避免与天文季节混淆

标签: r date


【解决方案1】:

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

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 以获得下个月的日期,dd 对应的季度是季节,因此使用 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'))

【讨论】:

  • 谢谢大家,这些都是很有帮助的回复
【解决方案2】:

仅使用base R,您可以将“日期时间”列转换为“日期”类(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

或者如cmets中提到的@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)

【讨论】:

  • 他们有一个日期时间列而不是日期列。您可以只使用strptime 并从POSIXlt 中提取mon
  • 当然可以,但是请查看 OP 损坏的示例数据中的 "
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
  • 2016-02-10
  • 2021-04-15
相关资源
最近更新 更多