在data.frame中将月份“factor”分类为时间段 更新(以下初始问题)

在data.frame中将月份“factor”分类为时间段 更新(以下初始问题),r,if-statement,time,recode,R,If Statement,Time,Recode,多亏了,我意识到我最初的例子不够复杂,因为我只有一年的时间。涵盖几年的数据可能更现实,对其他人更有用 换言之,我的数据是 df <- structure(list(yr_month = structure(1:7, .Label = c("2014-1", "2014-2", "2014-3", "2015-4", "2016-4", "2016-6", "2017-7"), class = "factor"), a = c(4.14, 2.83, 3.71, 4.15, 4.

多亏了,我意识到我最初的例子不够复杂,因为我只有一年的时间。涵盖几年的数据可能更现实,对其他人更有用

换言之,我的数据是

df <- structure(list(yr_month = structure(1:7, .Label = c("2014-1", "2014-2", 
"2014-3", "2015-4", "2016-4", "2016-6", "2017-7"), class = "factor"), 
    a = c(4.14, 2.83, 3.71, 4.15, 4.63, 4.91, 5.31), b = c(4.25, 
    3.5, 3.5, 3.5, 3.5, 3.5, 5)), .Names = c("yrQ", "a", "b"
), row.names = c(NA, 7L), class = "data.frame")
df
#      yrQ    a    b
# 1 2014-1 4.14 4.25
# 2 2014-2 2.83 3.50
# 3 2014-3 3.71 3.50
# 4 2015-4 4.15 3.50
# 5 2016-4 4.63 3.50
# 6 2016-6 4.91 3.50
# 7 2017-7 5.31 5.00
初始问题 假设我有一个这样的数据集

#   yr.cat    yrQ    a    b
# 1    "A" 2014-1 4.14 4.25
# 2    "A" 2014-2 2.83 3.50
# 3    "B" 2014-3 3.71 3.50
# 4    "B" 2015-4 4.15 3.50
# 5    "B" 2016-4 4.63 3.50
# 6    "C" 2016-6 4.91 3.50
# 7    "C" 2017-7 5.31 5.00
df <- structure(list(yr_month = structure(1:7, .Label = c("2016-1", "2016-2", 
"2016-3", "2016-4", "2016-5", "2016-6", "2016-7"), class = "factor"), 
    a = c(4.14, 2.83, 3.71, 4.15, 4.63, 4.91, 5.31), b = c(4.25, 
    3.5, 3.5, 3.5, 3.5, 3.5, 5)), .Names = c("yrQ", "a", "b"
), row.names = c(NA, 7L), class = "data.frame")
df
#      yrQ    a    b
# 1 2016-1 4.14 4.25
# 2 2016-2 2.83 3.50
# 3 2016-3 3.71 3.50
# 4 2016-4 4.15 3.50
# 5 2016-5 4.63 3.50
# 6 2016-6 4.91 3.50
# 7 2016-7 5.31 5.00
但是,如果我想装箱一个表示某个时间段的变量呢。比如在2016年3月之前,
2016-3
,在
2016-3
2016-5
之间,以及在
2016-5
之后。我意识到我可以将数据转换为
ts
,然后使用
window()
将其切碎,然后重新组合,但是使用
yrQ
上的if-else不是一种更聪明的方法吗

这是我想去的地方

  yr.cat    yrQ    a    b
1    "A" 2016-1 4.14 4.25
2    "A" 2016-2 2.83 3.50
3    "B" 2016-3 3.71 3.50
4    "B" 2016-4 4.15 3.50
5    "B" 2016-5 4.63 3.50
6    "C" 2016-6 4.91 3.50
7    "C" 2016-7 5.31 5.00

从“yrQ”中提取月份子字符串后,我们可以使用
cut

df$yr.cat <- cut(as.numeric(sub(".*-", "", df$yrQ)), 
               breaks = c(-Inf,2, 5, Inf), labels = LETTERS[1:3])
df$yr.cat
#[1] A A B B B C C
#Levels: A B C

问题中提供的输入数据与数据结构中不同点的
yrQ
yru-month
相同列不一致。我们假设该输入与
中的
yrQ
相同,只是我们将
名称中的
yrQ
替换为
yru-month
,以与
列表()中显示的相同名称保持一致

给予:

  yr_month    a    b yr.cat
1 Jan 2014 4.14 4.25      A
2 Feb 2014 2.83 3.50      A
3 Mar 2014 3.71 3.50      B
4 Apr 2015 4.15 3.50      B
5 Apr 2016 4.63 3.50      B
6 Jun 2016 4.91 3.50      C
7 Jul 2017 5.31 5.00      C
2)若要在没有任何包的情况下执行此操作,请将(1)中标记为##的行更改为下面的代码行。在这里,我们将
yr\u month
转换为
“Date”
类,然后删除其字符表示的日部分。这将为月份保留2位数字,以便1和2个数字月份之间的比较正常工作。(在(1)
“yearmon”
类中自动处理。)


df$yr\u month如果您的数据集包含2016年以外的日期,您可以使用
zoo
来推广这种方法。例如,
cut(as.numeric(zoo::as.yearmon(df$yrQ)),breaks=c(-Inf,2016.1,2016.4,Inf),labels=LETTERS[1:3])
。太棒了,谢谢。我意识到我简化的例子不够复杂,因为我只花了一年时间。我的真实数据已经有好几年了。如果
yrQ
字符串为
c(“2014-1”、“2014-2”、“2014-3”、“2014-4”、“2016-4”、“2016-6”、“2017-6”),请问您如何处理
取而代之?@ulfelder,谢谢。我将尝试这种方法并更新我的问题。但是,我希望避免过度转换
数据。框架
。@Eric我正要对年度部分发表评论。请更新您的question@ulfelder,我目前正在使用你的方法。我喜欢它的通用性,它只是间接转换g将数据转换为时间序列。如果您有时间,我将非常感谢您将其添加为答案。谢谢。谢谢您对我的问题的详尽回答!
cut(as.numeric(sub("-", ".", df$yrQ)),
       breaks = c(-Inf, 2014.2, 2016.5, Inf), labels = LETTERS[1:3])
#[1] A A B B B C C
#Levels: A B C
df <- structure(list(yr_month = structure(1:7, .Label = c("2014-1", "2014-2", 
"2014-3", "2015-4", "2016-4", "2016-6", "2017-7"), class = "factor"), 
    a = c(4.14, 2.83, 3.71, 4.15, 4.63, 4.91, 5.31), b = c(4.25, 
    3.5, 3.5, 3.5, 3.5, 3.5, 5)), .Names = c("yr_month", "a", "b"
), row.names = c(NA, 7L), class = "data.frame")
library(zoo)

df$yr_month <- as.yearmon(df$yr_month) ##
transform(df, yr.cat = LETTERS[ (yr_month >= "2014-03") + (yr_month > "2016-04") + 1])
  yr_month    a    b yr.cat
1 Jan 2014 4.14 4.25      A
2 Feb 2014 2.83 3.50      A
3 Mar 2014 3.71 3.50      B
4 Apr 2015 4.15 3.50      B
5 Apr 2016 4.63 3.50      B
6 Jun 2016 4.91 3.50      C
7 Jul 2017 5.31 5.00      C
df$yr_month <- sub("...$", "", as.Date(paste0(df$yr_month, -1)))