【问题标题】:How do I get year and month when day is invalid without fixing the day myself?我如何在不自己修复日期的情况下获得日期无效的年份和月份?
【发布时间】:2023-04-08 22:44:01
【问题描述】:

我有一些看起来有点像这样的数据:

require(zoo)

X <- rbind(c(date='20111001', fmt='%Y%m%d'),
            c('20111031', '%Y%m%d'),
            c('201110', '%Y%m'),
            c('102011', '%m%Y'),
            c('31/10/2011', '%d/%m/%Y'),
            c('20111000', '%Y%m%d'))
print(X)

#      date       fmt     
# [1,] "20111001" "%Y%m%d"
# [2,] "20111031" "%Y%m%d"
# [3,] "201110"   "%Y%m"  
# [4,] "102011"   "%m%Y"  
# [5,] "31/10/2011" "%d/%m/%Y"
# [6,] "20111000" "%Y%m%d"

我只想要年份和月份。我不需要那一天,所以我不担心最后一天无效。不幸的是,R 是:

mapply(as.yearmon, X[, 'date'], X[, 'fmt'], SIMPLIFY=FALSE)

# $`20111001`
# [1] "Oct 2011"

# $`20111031`
# [1] "Oct 2011"

# $`201110`
# [1] "Oct 2011"

# $`102011`
# [1] "Oct 2011"

# $`31/10/2011`
# [1] "Oct 2011"

# $`20111000`
# Error in charToDate(x) : 
#   character string is not in a standard unambiguous format

我知道通常的答案是修复日期的日期部分,例如使用paste(x, '01', sep='')。我认为这在这里行不通,因为我事先不知道日期格式是什么,因此如果不先转换为某种日期对象,我就无法设置日期。

【问题讨论】:

  • as.yearmon 在什么包中?代码应该是可重现的。此外,您还在示例数据中强制使用整数来表示字符,所以这并不理想。
  • @mdsumner: as.yearmon 在 zoo 包中。
  • 我知道,但它应该在 q 中——我现在看到了
  • 您需要更清楚 "get the year and month" 是否意味着 作为字符串,或某种日期类型,或任何东西 ?似乎您的意思是作为某种数据类型(在本例中为 zoo::yearmon)。你能编辑你的标题清楚吗? (我不知道你想要什么,否则我会自己编辑)

标签: r date


【解决方案1】:

假设月份总是跟在年份之后,并且在您的date 中始终是两个字符。为什么不直接使用substr 提取信息。可能是这样的:

lapply(X[,'date'], 
  function(x) paste(month.abb[as.numeric(substr(x, 5, 6))], substr(x, 1, 4))
  )

【讨论】:

  • 我现在使用as.yearmon(substr(X[,'date'], 1, 6), '%Y%m'),但我不想假设前6个字符总是'%Y%m'。我将更改示例数据以反映这一点。
【解决方案2】:

如果不需要,则无需在格式中指定日期。仔细阅读?strptime。详细信息部分的第二段说:

每个输入字符串 尽可能按指定格式处理:任何 尾随字符被忽略。

所以调整你的格式,一切都会正常。

X <- rbind(c(date='20111001', fmt='%Y%m'),
           c('20111031', '%Y%m'),
           c('201110',   '%Y%m'),
           c('102011',   '%m%Y'),
           c('20111000', '%Y%m'))
mapply(as.yearmon, X[, 'date'], X[, 'fmt'], SIMPLIFY=FALSE)

【讨论】:

  • 格式随日期一起提供给我。我可以通过使用stringr 中的str_replace 从格式字符串中删除/替换'%d' 来修改给定的格式,但这仅在日期位于字符串末尾时才有效。
【解决方案3】:

假设我总是得到一个日期(而不是时间),并且任何非法的“天”都小于 61,我可以通过将提供的日期视为“秒”和用第一天替换提供的日期。

require(stringr)

safe_date <- str_c('01', X[, 'date'])
safe_fmt <- str_c('%d', str_replace(X[, 'fmt'], '%d', '%S'))

mapply(as.yearmon, safe_date, safe_fmt, SIMPLIFY=FALSE)

# $`0120111001`
# [1] "Oct 2011"

# $`0120111031`
# [1] "Oct 2011"

# $`01201110`
# [1] "Oct 2011"

# $`01102011`
# [1] "Oct 2011"

# $`0131/10/2011`
# [1] "Oct 2011"

# $`0120111000`
# [1] "Oct 2011"

【讨论】:

    猜你喜欢
    • 2021-12-16
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多