【问题标题】:calculate age in years and months and melt data以年和月为单位计算年龄并融化数据
【发布时间】:2012-05-15 04:08:32
【问题描述】:

我正在处理一些时间数据,但在将时差转换为年和月时遇到问题。

我的数据或多或少是这样的,

dfn <- data.frame(
Today  = Sys.time(),
DOB  = seq(as.POSIXct('2007-03-27 00:00:01'), len= 26, by="3 day"),
Patient  = factor(1:26, labels = LETTERS))

首先我从今天的数据 (Today) 中减去出生数据 (DOB)。

dfn$ageToday <-  dfn$Today - dfn$DOB

这给了我Time difference in days

dfn$ageToday
 Time differences in days
  [1] 1875.866 1872.866 1869.866 1866.866 1863.866
  [6] 1860.866 1857.866 1854.866 1851.866 1848.866
 [11] 1845.866 1842.866 1839.866 1836.866 1833.866
 [16] 1830.866 1827.866 1824.866 1821.866 1818.866
 [21] 1815.866 1812.866 1809.866 1806.866 1803.866
 [26] 1800.866
 attr(,"tzone")
 [1] ""

这是我的问题的第一部分; 如何将此差异转换为年和月(四舍五入为月)?(即 4.7、4.11 等)

我阅读了?difftime 手册页和?format,但我没有弄明白。

任何帮助将不胜感激。

此外,我想融化我的最终对象,如果我尝试使用这个命令在上面的数据框上使用融化,

require(plyr)
require(reshape)
mdfn <- melt(dfn, id=c('Patient'))

我收到了这个我以前从未见过的奇怪警告

Error in as.POSIXct.default(value) : 
  do not know how to convert 'value' to class "POSIXct"

所以,我的第二个问题是; 如何在meltPOSIXct 变量旁边创建时差?

谢谢,埃里克

【问题讨论】:

    标签: r time


    【解决方案1】:

    lubridatepackage 使处理日期和时间(包括查找时差)变得非常容易。

    library("lubridate")
    library("reshape2")
    
    dfn <- data.frame(
        Today  = Sys.time(),
        DOB  = seq(as.POSIXct('2007-03-27 00:00:01'), len= 26, by="3 day"),
        Patient  = factor(1:26, labels = LETTERS))
    
    dfn$diff <- new_interval(dfn$DOB, dfn$Today) / duration(num = 1, units = "years")
    
    mdfn <- melt(dfn, id=c('Patient'))
    class(mdfn$value) # all values are coerced into numeric
    

    new_interval() 函数计算两个日期之间的时间差。请注意,有一个函数today() 可以替代您对Sys.time 的使用。最后请注意 duration() 函数,它创建了一个标准的 ehm 持续时间,您可以使用该函数将间隔除以标准单位的长度,在本例中为一年。

    如果您想保留TodayDOB 的内容,那么您可能需要先将所有内容转换为character,然后再重新转换...

    library("lubridate")
    library("reshape2")
    
    dfn <- data.frame(
      Today  = Sys.time(),
      DOB  = seq(as.POSIXct('2007-03-27 00:00:01'), len= 26, by="3 day"),
      Patient  = factor(1:26, labels = LETTERS))
    
    # Create standard durations for a year and a month
    one.year <- duration(num = 1, units = "years")
    one.month <- duration(num = 1, units = "months")
    
    # Calculate the difference in years as float and integer
    dfn$diff.years <- new_interval(dfn$DOB, dfn$Today) / one.year
    dfn$years <- floor( new_interval(dfn$DOB, dfn$Today) / one.year )
    
    # Calculate the modulo for number of months
    dfn$diff.months <- round( new_interval(dfn$DOB, dfn$Today) / one.month )
    dfn$months <- dfn$diff.months %% 12
    
    # Paste the years and months together
    # I am not using the decimal point so as not to imply this is
    # a numeric representation of the diference
    dfn$y.m <- paste(dfn$years, dfn$months, sep = '|')
    
    # convert Today and DOB to character so as to preserve them in melting
    dfn$Today <- as.character(dfn$Today)
    dfn$DOB <- as.character(dfn$DOB)
    
    # melt using string representation of difference between the two dates
    dfn2 <- dfn[,c("Today", "DOB", "Patient", "y.m")]
    mdfn2 <- melt(dfn2, id=c('Patient'))
    
    # alternative melt using numeric representation of difference in years
    dfn3 <- dfn[,c("Today", "DOB", "Patient", "diff.years")]
    mdfn3 <- melt(dfn3, id=c('Patient'))
    

    【讨论】:

    • 感谢您回答我的问题。它几乎就在那里,尽管它没有将年龄四舍五入到几个月。它显示年龄为 2.96 岁,我希望是 3 岁,小数点后的任何内容都不应大于 0.11(如果这有意义?)
    • @eric-d-brean -- 我已经扩展了我的第二个代码 sn-p 为您提供了几种接近目标的方法......从这里到什么应该很容易你打算。我给你几个选择。
    猜你喜欢
    • 2015-05-21
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    相关资源
    最近更新 更多