Почему я должен установить as.Date origin снова после использования ifelse? Есть ли способ лучше? - PullRequest
3 голосов
/ 06 декабря 2010

Следующая функция работает, но последняя часть 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)
}

Это возвращало исправленные значения всякий раз, когда условие было ЛОЖЬ (нет), новернул NA, если условие было TRUE (да).Это почему?И если я использую функцию выше, почему я должен снова определить источник?Почему у меня даже есть вызов as.Date снова?

EDIT:

 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.

1 Ответ

2 голосов
/ 06 декабря 2010

Ваша конструкция как минимум "интересна".Начнем с того, что ни x, ни y не выводят.Интересно, почему вы используете назначение в вашем eval().это дает вам вектор resDate, который точно соответствует последнему вызову.И это не зависит от условия, оно написано последним (eval(x) в вашем случае).Они выполняются до того, как будет выполнено предложение ifelse.

Кроме того, вы получите числовое представление ваших данных, а не объект данных.Это в resDate.Я предполагаю, что ifelse не может определить класс выходного вектора, так как вы используете eval() внутри.Я удивлен, что вы получаете вывод вообще, фактически вы используете что-то, что можно было бы назвать «ошибкой» в R (Microsoft назвал бы это функцией :-)).

Ваша ошибка вваш 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, но использование индексов, как правило, быстрее.


РЕДАКТИРОВАТЬ:

Это проще для данныхпоколение:

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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...