将年月字符串列转换为季度分类

时间:2015-11-08 18:54:51

标签: r text-processing date-formatting binning

我目前正在处理大型物候数据集,其中对于给定月份存在多个树木观测值。我想将这些观察结果分配到三个月的集群或箱子中。我目前正在使用以下代码:

Cluster.GN <- ifelse(Master.feed.parts.gn$yr.mo=="2007.1", 1,
              ifelse(Master.feed.parts.gn$yr.mo=="2007.11", 1,....     
              ifelse(Master.feed.parts.gn$yr.mo=="2014.05", 17, NA)

此代码有效,但由于有超过50个月的时间,因此非常繁琐。我找不到另一个解决方案,因为这个&#34; binning&#34;不是基于观测数量(因为在每个月内可以有多达4000个观测值)并且不是按时间顺序排列的,因为缺少几个月。您可以提供的任何帮助将非常感谢。

更新I:我使用&#34; cut&#34;在R.我尝试将休息时间设置为17,因为那是我应该拥有多少三个月的垃圾箱。但是当我使用表格(Cluster.GN)时,它显示只有奇数编号的&#34; bins&#34;有观察(抱歉,但我无法弄清楚如何将表格上传到此处)。 &gt; Cluster.GN&lt; - cut(Master.feed.parts.gn $ yr.mo,break = 17,c(&#34; 1&#34;,&#34; 2&#34;,&#34; 3&#34;,&#34; 4&#34;,&#34; 5&#34;,&#34; 6&#34;,&#34; 7&#34;,&#34; 8&#34;, &#34; 9&#34;,&#34; 10&#34;,&#34; 11&#34;,&#34; 12&#34;,&#34; 13&#34;,&#34; 14& #34;,&#34; 15&#34;,&#34; 16&#34;,&#34; 17&#34;),include.lowest = TRUE)

1 个答案:

答案 0 :(得分:0)

更新:这个答案是一个快速的黑客,我没有检查zoo库。有关正确的方法,请参阅G Grothendieck's answer using zoo::as.yearqtr()

您需要做的就是将yr.mo字段从年 - 月字符串(例如2007.11)转换为1..17范围内的整数,每个季度(即第1个月) ..3进入第一个bin,4..6进入第二个bin等)。 (我不知道8年(2007年至2014年)* 4季度= 32个箱子减少到只有17个箱子,除非你的数据稀疏。但无论如何......)

不需要繁琐的ifelse梯子。

要获得更高的性能,请使用stringi库,stri_split_fixed()

sample_wr <- function(...) sample(..., replace=T)

# Generate sample data (you're supposed to provide this to code, to make your issue reproducible)
set.seed(123)
N <- 20
df <- data.frame(yr.mo =
          paste(sample_wr(2007:2014, N), sample_wr(1:12, N), sep='.') )
# [1] "2009.11" "2013.9"  "2010.8"  "2014.12" "2014.8"  "2007.9"  "2011.7" 
# [8] "2014.8"  "2011.4"  "2010.2"  "2014.12" "2010.11" "2012.9"  "2011.10"
#[15] "2007.1"  "2014.6"  "2008.10" "2007.3"  "2009.4"  "2014.3" 

yearmonth_to_integer <- function(xx) {
    yy_mm <- as.integer(unlist(strsplit(xx, '.', fixed=T)))
    return( (yy_mm[1] - 2006) + (yy_mm[2] %/% 3) )
}

Cluster.GN <- sapply(x, yearmonth_to_integer)

# 2009.11  2013.9  2010.8 2014.12  2014.8  2007.9  2011.7 
#    6      10       6      12      10       4       7 
# 2014.8  2011.4  2010.2 2014.12 2010.11  2012.9 2011.10 
#   10       6       4      12       7       9       8 
# 2007.1  2014.6 2008.10  2007.3  2009.4  2014.3 
#    1      10       5       2       4       9 

并且为了获得更高的性能,请使用dplyr或data.table库:

require(dplyr)

# something like the following, currently doesn't work,
# you have to handle two intermediate columns from yy_mm
# You get to fix this :)

df %>% mutate(yy_mm = as.integer(unlist(strsplit(yr.mo, '.', fixed=T))),
              quarter = yy_mm[1]-2006 + yy_mm[2] %/% 3 )