将年月字符串列转换为季度分箱
Convert year-month string column into quarterly bins
我目前正在处理一个大型物候学数据集,其中对给定月份的树木进行了多次观察。我想将这些观察结果分配到三个月的集群或容器中。我目前正在使用以下代码:
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多个月了。我很难找到另一个解决方案,因为这个 "binning" 不是基于观察的数量(因为每个月内最多可以有 4000 个观察)并且它不是按时间顺序排列的,因为有些月份丢失了。您可以提供的任何帮助将不胜感激。
更新 I:我在 R 中使用了 "cut" 函数。我尝试将休息时间设置为 17,因为这是我应该有多少三个月的垃圾箱。但是当我使用 table(Cluster.GN) 时,它显示只有奇数 "bins" 有观察结果(抱歉,我不知道如何在此处上传 table ). >Cluster.GN <- cut(Master.feed.parts.gn$yr.mo, breaks= 17, c("1", "2", "3", "4", "5", "6 ", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17"), include.lowest=真)
更新:这个答案是一个快速破解,我没有检查 zoo
库。正确的做法请看
您需要做的就是将 yr.mo
字段从年月字符串(例如 2007.11
)转换为 1..17 范围内的整数,每个季度(即月 1..3 进入第一个垃圾箱,4..6 个月进入第二个垃圾箱等)。 (我不知道 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 )
我目前正在处理一个大型物候学数据集,其中对给定月份的树木进行了多次观察。我想将这些观察结果分配到三个月的集群或容器中。我目前正在使用以下代码:
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多个月了。我很难找到另一个解决方案,因为这个 "binning" 不是基于观察的数量(因为每个月内最多可以有 4000 个观察)并且它不是按时间顺序排列的,因为有些月份丢失了。您可以提供的任何帮助将不胜感激。
更新 I:我在 R 中使用了 "cut" 函数。我尝试将休息时间设置为 17,因为这是我应该有多少三个月的垃圾箱。但是当我使用 table(Cluster.GN) 时,它显示只有奇数 "bins" 有观察结果(抱歉,我不知道如何在此处上传 table ). >Cluster.GN <- cut(Master.feed.parts.gn$yr.mo, breaks= 17, c("1", "2", "3", "4", "5", "6 ", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17"), include.lowest=真)
更新:这个答案是一个快速破解,我没有检查 zoo
库。正确的做法请看
您需要做的就是将 yr.mo
字段从年月字符串(例如 2007.11
)转换为 1..17 范围内的整数,每个季度(即月 1..3 进入第一个垃圾箱,4..6 个月进入第二个垃圾箱等)。 (我不知道 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 )