以下函数确实有效,但最后的 as.Date 部分或多或少是不完全理解的反复试验的结果。
### This function creates a real date column out of year / period that is saved in
### in separate columns, plus it handles a 13th period in case of overlapping period
### terminology. Turns quarters into months.
realDate <- function (table,year="year_col",period="period_col"){
if (is.character(table) == TRUE)
{
dframe <- get(table)
}
else{
dframe <- table
}
x <- expression({resDate <- with(dframe,
as.Date(paste(get(year),"-",
ifelse(get(period) > 9, get(period),
paste("0", get(period), sep = "")),
"-01", sep = "")))
})
y <- expression({resDate <- with(dframe,as.Date(paste(get(year) + 1,"-","01","-01",sep="")))})
#### I do not get this? Why do I have to do this?
a <- ifelse(get(period) == 13,eval(y),eval(x))
a <-as.Date(a, origin="1970-01-01")
return(a)
}
相反,我尝试这样做(因为它对我来说更直观):
{ ....
ifelse(get(period) == 13,eval(y),eval(x))
return(resDate)
}
每当条件为 FALSE(否)时返回更正值,但如果条件为 TRUE(是)则返回 NA。这是为什么?如果我使用上面的功能,为什么我必须重新定义原点?为什么我还要再次调用 as.Date?
编辑:
a <- rep(2002:2010,2)
b <- rep(1:13,2)
d<-cbind(a,b[1:length(a)])
names(d) <- c("year_col","period_col")
附言: 我找到了这个 thread在向量化的 ifelse 上。
最佳答案
你的构造至少是“有趣的”。首先,x 和 y 都没有给出输出。我想知道您为什么在 eval()
中使用赋值。这为您提供了一个 resDate 向量,它正是上次调用的内容。这不依赖于条件,它是最后一个写的(eval(x)
在你的情况下)。它们在 ifelse 子句执行之前执行。
此外,您获得的输出是数据的数字表示,而不是数据对象。那是在 resDate 中。我猜 ifelse
无法确定输出向量的类,因为您在内部使用了 eval()
。我很惊讶你能得到输出,事实上,你有效地使用了一些在 R 中可以称为“错误”的东西(微软会称之为功能 :-))。
你的错误在你的 ifelse 中:get(period)
不存在。它应该是 get(period, dframe)
。然后就可以了。它在您的计算机上运行的唯一原因是,大概是因为您的工作区中有一个 period
。调试时出现Classis问题。
无论如何,我会做到:
realDate <- function (table,year="year_col",period="period_col"){
if (is.character(table)){ # is.character(table) returns a boolean already.
dframe <- get(table)
} else {
dframe <- table
}
year <- get(year,dframe)
period <- get(period,dframe)
year[period==13] <- year[period==13]+1
period[period==13] <- 1
as.Date(paste(year,"-",period,"-01",sep=""))
}
这比您自己的快很多,陷阱和转换更少,而且更像是 R 的实现方式。您可以通过 ifelse 结构更改 year[...] 和 period [...],但使用索引通常更快。
编辑:
这对于数据生成来说更容易:
dframe <- data.frame(
year_col= rep(2006:2007,each=13),
period_col = rep(1:13,2)
)
realDate(dframe)
[1] "2006-01-01" "2006-02-01" "2006-03-01" "2006-04-01" "2006-05-01"
"2006-06-01" "2006-07-01" "2006-08-01" "2006-09-01"
[10] "2006-10-01" "2006-11-01" "2006-12-01" "2007-01-01" "2007-01-01"
"2007-02-01" "2007-03-01" "2007-04-01" "2007-05-01"
[19] "2007-06-01" "2007-07-01" "2007-08-01" "2007-09-01"
"2007-10-01" "2007-11-01" "2007-12-01" "2008-01-01"
关于r - 为什么使用ifelse后还要重新设置as.Date origin?有没有更好的办法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4365523/