为什么在使用ifelse之后必须再次将as.Date原点设置为?有没有更好的办法? [英] Why do I have to set as.Date origin again after using ifelse? Is there a better way?

查看:89
本文介绍了为什么在使用ifelse之后必须再次将as.Date原点设置为?有没有更好的办法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下功能确实起作用,但最后一个as.Date部分或多或少是反复试验的结果,无法完全理解。

The following function does work, but the last as.Date part was more or less an result of trial and error that do not understand fully.

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

}

相反,我尝试这样做(因为对我而言更直观):

Instead I tried to do it like this (because it was more intuitively to me):

{ ....
ifelse(get(period) == 13,eval(y),eval(x))
return(resDate)
}

只要条件为FALSE(否),它就返回校正后的值;但如果条件为TRUE(是),则返回NA。这是为什么?如果使用上面的函数,为什么还要重新定义原点?为什么我甚至还要再次呼叫as.Date?

This returned the corrected values whenever the condition was FALSE (no) but returned NA if the condition was TRUE (yes). Why is that? And if I use the function above, why do I have to define the origin again? Why I even have call as.Date again?

编辑:

 a <- rep(2002:2010,2)
 b <- rep(1:13,2)
 d<-cbind(a,b[1:length(a)])
 names(d) <- c("year_col","period_col")

PS :
我在向量化ifelse上发现了这个线程

推荐答案

您的构造至少有趣。首先,x和y都不给出输出。我想知道为什么在 eval()中使用赋值。这将为您提供一个resDate向量,该向量正是上次调用的结果。这与条件无关,它是最后一个写的(在您的情况下为 eval(x))。它们在执行ifelse子句之前就已执行。

Your construct is "interesting" at least. To start with, neither x nor y gives output. I wonder why you use an assignment in your eval(). this gives you a resDate vector that is exactly what the last call has been. And that is not dependent on the condition, it's the last one written (eval(x) in your case). They get executed before the ifelse clause is executed.

此外,您得到的输出是数据的数字表示形式,而不是数据对象。那是在resDate中。我猜想 ifelse 不能确定输出向量的类,因为您在其中使用了 eval()。令我惊讶的是,您根本无法获得输出,实际上您实际上在使用R中可能被称为错误的东西(Microsoft称它为功能:-))。

Plus, the output you get is the numeric representation of your data, not the data object. That is in resDate. I guess that ifelse cannot determine the class of the output vector as you use the eval() inside. I'm surprised you get output at all, in fact you're effectively using something that could be called a "bug" in R (Microsoft would call it a feature :-) ).

您的错误在于您的ifelse: get(period)不存在。应该是 get(period,dframe)。然后就可以了。它在您的计算机上运行的唯一原因是,大概您的工作空间中有一个期间。调试时出现类问题。

Your mistake is in your ifelse : get(period) doesn't exist. it should be get(period, dframe). Then it works. The only reason why it works on your computer, is because you have a period in your workspace presumably. Classis problem when debugging.

无论如何,我都会做到:

In any case, I'd make it:

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构造来更改年份和期间,但是使用索引通常更快。

This is quite a bit faster than your own, has less pitfalls and conversions, and is more the R way of doing it. You could change year[...] and period [...] by ifelse constructs, but using indices is generally faster.

编辑:

这更易于生成数据:

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"

这篇关于为什么在使用ifelse之后必须再次将as.Date原点设置为?有没有更好的办法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆