难以用R中的日期执行算术

时间:2013-12-17 08:14:05

标签: r time date-arithmetic

我正在操纵包含日期的数据,并且遇到了一些麻烦。基本上我希望根据我的数据帧中的所有行,基于两个现有日期和另一个变量计算新日期。例如,我希望能够从Date1中减去10天,或者计算Date1和Date2之间的日期等。但是,在将新的计算日期添加到数据帧时,我无法理解类分配。示例数据框:

#  Uncomment to clear your session...
# rm(list = ls(all = TRUE))
tC <- textConnection("StudyID   Date1   Date2
C0031   2-May-09    12-Jan-10
C0032   7-May-09    30-Apr-10")
data <- read.table(header=TRUE, tC)
close.connection(tC)
rm(tC)

#CONVERTING TO DATES    
data$Date1 <- with(data,as.Date(Date1,format="%d-%b-%y"))
data$Date2 <- with(data,as.Date(Date2,format="%d-%b-%y"))

现在我的问题开始了

class(data[1, "Date2"] - 10) # class is "Date". So far so good. 
data[1, "newdate"]  <- (data[1, "Date2"] - 10)
class(data[1, "newdate"]) # class is now "numeric"... 

尝试了

data[1, "newdate"]  <- as.Date(data[1, "Date2"] - 10)
class(data[1, "newdate"]) # doesn't help. Class still "numeric"... 

只是不明白为什么这个值在分配给数据时会变成数字

2 个答案:

答案 0 :(得分:2)

问题是由于列newdate不存在并且分配单个值:

# create a single value in a new column
data[1, "newdate"]  <- data[1, "Date2"] - 10
class(data[1, "newdate"]) # numeric 

# create the whole column
data[ , "newdate2"] <- data[1, "Date2"] - 10
class(data[1, "newdate2"]) # Date

# create a column of class Date before assigning value
data[ , "newdate3"] <- as.Date(NA)
data[1, "newdate3"] <- data[1, "Date2"] - 10
class(data[1, "newdate3"]) # Date

顺便说一句,在使用as.Date个对象执行数学运算时,您不需要Date

答案 1 :(得分:0)

问题在于回收矢量剥离属性。正如我在评论中所述,使用例如data$newdate <- data$Date1 - 10创建整个列而不回收向量,从而保留Date等属性。考虑下面的说明性玩具示例:

# Simple vector with an attribute
x <- 1:3
attributes(x) <- list( att = "some attributes" )
x
#[1] 1 2 3
#attr(,"att")
#[1] "some attributes"

# Simple data.frame with 3 rows
df <- data.frame( a = 1:3 )

#  New column using first element of vector with attributes
df$b <- x[1]

#  It is recycled to correct number of rows and attributes are stripped
str(df$b)
# int [1:3] 1 1 1

#  Without recycling attributes are retained
df$c <- x
str(df$c)
# atomic [1:3] 1 2 3
# - attr(*, "att")= chr "some attributes"

#  But they all look the same...
df
#  a b c
#1 1 1 1
#2 2 1 2
#3 3 1 3

并根据您的数据..

attributes(data$Date1)
# $class
# [1] "Date"