【问题标题】:Create Quarterly Subsets in R在 R 中创建季度子集
【发布时间】:2014-05-21 23:21:41
【问题描述】:

我有一个包含多年时间数据的数据框。它还有其他数据,如姓名、金额和日期。我想将数据框子集为年度季度,以衡量相应季度的某些方面。例如,我只想查看 1 月、2 月和 3 月的收入。

我已确定日期列是时间序列:

class(data_frame$launch_date)
>"Date"

我已经尝试过这段代码,以获取第一季度/前几个月的数据:

subset(data_frame, format.Date(launch_date, "%m") <= "03")

但它并没有给我一个新的数据框和这个响应:

<0 rows> (or 0-length row.names)

我试过了

data_frame_q1 <- data.frame(data_frame, data_frame$launched < as.Date("2013-03-31"))

但我没有得到数据的子集。

建议?

【问题讨论】:

  • 使用lubridate::quarter
  • 另外,只是收紧术语,您已确保日期列是“日期”类,这很好,但时间序列是它自己的类,而不是您拥有的。跨度>

标签: r date


【解决方案1】:

似乎对我有用,不确定你做了什么:

data_frame <- data.frame(
 id=1:5,
 launch_date=seq.Date(as.Date("2014-01-01"),as.Date("2014-05-01"),by="1 month")
)

#  id launch_date
#1  1  2014-01-01
#2  2  2014-02-01
#3  3  2014-03-01
#4  4  2014-04-01
#5  5  2014-05-01

class(data_frame$launch_date)
#[1] "Date"

subset(data_frame, format.Date(launch_date, "%m") <= "03")

#  id launch_date
#1  1  2014-01-01
#2  2  2014-02-01
#3  3  2014-03-01

虽然使用实际数字可能更安全并这样做:

subset(data_frame, as.numeric(format(launch_date, "%m")) <= 3)

#  id launch_date
#1  1  2014-01-01
#2  2  2014-02-01
#3  3  2014-03-01

【讨论】:

    【解决方案2】:

    您已经很接近了,但您需要学习如何正确地对数据进行子集化。

    一些cmets:不要使用subset。它有效,但您应该习惯于更“R”的做事方式。使用[ 子集您的数据框。其次,如果函数的参数是Date,则不需要专门调用format.Date;你可以打电话给format,R 会为你选择合适的函数。

    所以,您的函数不起作用的原因是因为您将character 类型与&lt;= 进行比较,这是不允许的。将它们转换为数字,它将起作用:。我不知道为什么你的原件不起作用。它对我有用。

    # Generate some data
    set.seed(1)
    n<-100
    data_frame<-data.frame(launch_date=as.Date(Sys.time())+runif(n,1,365))
    
    subset(data_frame,as.numeric(format(launch_date, "%m"))<=3)
    

    但是,不要使用subset,而是尝试使用[ 运算符:

    data_frame[as.numeric(format(data_frame$launch_date, "%m"))<=3,]
    

    这只是意味着返回as.numeric(format(data_frame$launch_date, "%m"))&lt;=3TRUE 的所有行。

    如果你想把你的数据分成四份,你可以做一个小映射表:

    quarters.map<-data.frame(month=1:12,quarter=rep(1:4,each=3))
    #    month quarter
    # 1      1       1
    # 2      2       1
    # 3      3       1
    # 4      4       2
    # 5      5       2    
    

    然后只需merge 就可以了:

    head(merge(data_frame,quarters.map))
    #   month launch_date quarter
    # 1     1  2015-01-14       1
    # 2     1  2015-01-17       1
    # 3     1  2015-01-29       1
    # 4     1  2015-01-20       1
    # 5     1  2015-01-10       1
    # 6     1  2015-01-17       1
    

    【讨论】:

    • "您正在与带有 " - "02" &lt;= "03""04" &lt;= "03"
    • 虽然它可能会导致问题,例如"05" &lt; paste0("0",1:10)
    • 确实,我会避免它。但是,很明显我无法重现 OP 的错误。
    • 我也不知道错误是什么。但这个方法似乎奏效了!谢谢!
    【解决方案3】:

    我将为季度创建一个新变量。

    data_frame$quarter <- quarters(data_frame$launch_date)
    

    然后您可以像这样子集您的数据:

    subset(data_frame,quarter=='Q1')
    

    使用@thelatemail 数据:

    data_frame
      id launch_date quarter
    1  1  2014-01-01      Q1
    2  2  2014-02-01      Q1
    3  3  2014-03-01      Q1
    4  4  2014-04-01      Q2
    5  5  2014-05-01      Q2
    
    subset(data_frame,quarter=='Q1')
      id launch_date quarter
    1  1  2014-01-01      Q1
    2  2  2014-02-01      Q1
    3  3  2014-03-01      Q1
    

    【讨论】:

    • 或一步到位subset(data_frame, quarters(launch_date)=="Q1")
    【解决方案4】:

    只是将我的评论变成答案...

    library(lubridate)
    subset(data_frame, quarter(launch_date) == 1)
    
    ## Using @thelatemail's data
    
    > subset(data_frame, quarter(launch_date) == 1)
      id launch_date
    1  1  2014-01-01
    2  2  2014-02-01
    3  3  2014-03-01
    

    虽然我也对你的方法有什么问题感到困惑。也许你没有得到正确的列名?一开始你使用launch_date,但在你的data_frame_q1中你使用launched

    【讨论】:

    • 我认为问题是针对&lt;= 3 而不是== 3 btw。
    • @thelatemail 实际上是== 1,按季度计算。感谢收看!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    • 1970-01-01
    • 2014-08-09
    • 2014-08-11
    • 2021-01-08
    • 1970-01-01
    相关资源
    最近更新 更多