4

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

我的数据看起来或多或少是这样的,

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))

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

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"

所以,我的第二个问题是;如何在变量melt旁边创建时间差异POSIXctdfn$ageToday如果我没有一切就融化,就像魅力一样。

谢谢,埃里克

4

1 回答 1

5

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

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 持续时间的函数,您可以使用该函数将间隔除以标准单位的长度,在本例中为一年的单位。

如果您想保留 and 的内容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'))
于 2012-05-15T05:37:20.853 回答