【问题标题】:Change date variable to continuous month将日期变量更改为连续月份
【发布时间】:2017-09-04 21:41:42
【问题描述】:

我有一个数据框,其中有一列名为“日期”的列采用日期格式:

 df<- data.frame(date=c("1997-01-01", "1997-01-02", "1997-01-03", "1997-01-04", 
  "1997-01-05", "1997-01-06" ,"1997-01-07" ,"1997-01-08","1998-01-12", 
  "1998-01-13", "1998-01-14", "1998-01-15" ,"1998-01-16", "1998-01-17", 
   "1998-01-18", "1998-01-19"))

我需要创建一个列,将Date 列中的唯一年/月组合更改为连续的月份变量。我有 20 年的数据,并且有 1-240 个月的数据。

所以上面 df 的例子会返回:

output<- data.frame(date=c("1997-01-01", "1997-01-02", "1997-01-03", 
 "1997-01-04", "1997-01-05", "1997-01-06" ,"1997-01-07" ,"1997-01-08","1998-01-12", 
  "1998-01-13", "1998-01-14", "1998-01-15" ,"1998-01-16", "1998-01-17", 
   "1998-01-18", "1998-01-19"), continuous_month=c("1", "1", "1", "1", 
  "1", "1" ,"1" ,"1","13",  "13", "13", "13" ,"13", "13",  "13", "13"))

注意:01/1997 将是第一个月,我在示例数据框中跳过了 02/1997(第 2 个月)-12/1997(第 12 个月)的月份,因此 01/1998 将是第 13 个月系列。

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用lubridateyearmonth提取相关信息

    library(lubridate)
    df$date = ymd(df$date)
    temp = 12*(year(df$date) - min(year(df$date))) + month(df$date)
    df$output = temp - min(temp) + 1
    df$output
    # [1]  1  1  1  1  1  1  1  1 13 13 13 13 13 13 13 13
    

    【讨论】:

    • 除非最小月份是一月,否则我认为这不会给出正确的结果。
    • 谢谢,这个方法适用于我的数据,因为我的最小月份是一月。但是,@thelatemail 暗示的通用方法(不特定于一个数据集的细节)也会有所帮助。感谢您的宝贵时间
    • 如果数据集在 date 列中有 NA,那么此方法会产生一个包含所有 NA 的输出,知道如何使用上面建议的方法,并保留任何带有 NA 的行吗?例如,过滤 NA,执行函数并将原始数据帧与 NA 合并。
    【解决方案2】:

    1) yearmon 类

    "yearmon" 类在内部将年/月表示为年加上 0、1/12、2/12 等表示一月、二月、三月等,因此:

    library(zoo)
    
    ym <- as.yearmon(df$date)
    12 * (ym - ym[1]) + 1
    ## [1]  1  1  1  1  1  1  1  1 13 13 13 13 13 13 13 13
    

    2) POSIXlt 类

    使用"POSIXlt" 基类的解决方案是:

    with(as.POSIXlt(df$date), 12 * (year - year[1]) + mon - mon[1] + 1)
    ## [1]  1  1  1  1  1  1  1  1 13 13 13 13 13 13 13 13
    

    【讨论】:

    • as.POSIXlt 上的 unclass 也不是绝对需要的吗?
    【解决方案3】:

    我们可以使用base R

    df$continuous_month <- seq(1, 240, by = 12)[(as.integer(sub(".*-", "", df$date))%/%12) + 1]
    df$continuous_month
    #[1]  1  1  1  1  1  1  1  1 13 13 13 13 13 13 13 13
    

    【讨论】:

    • 我认为这个解决方案是错误的 - 它使用了“每月中的某天”部分的信息,这是不相关的。
    【解决方案4】:

    另一个基础R 解决方案,向数据中添加了更多变化:

    > # Format as date
    > df$date <- as.Date(df$date) 
    > 
    > # Add some more variations to the data
    > df$date <- df$date + sample(1:100, size = length(df$date)) 
    > 
    > # First the year difference and then the month difference.
    > df$continuous_month <- (as.integer(format(df$date, "%Y")) - 1997L) * 12L +
    +                        as.integer(format(df$date, "%m"))
    > df
             date continuous_month
    1  1997-01-28                1
    2  1997-02-05                2
    3  1997-01-31                1
    4  1997-01-09                1
    5  1997-01-15                1
    6  1997-01-29                1
    7  1997-03-23                3
    8  1997-02-24                2
    9  1998-02-20               14
    10 1998-02-18               14
    11 1998-01-17               13
    12 1998-02-22               14
    13 1998-02-01               14
    14 1998-04-06               16
    15 1998-02-12               14
    16 1998-03-01               15
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多