2013-09-12 5 views
7

Как мне векторизовать эту функцию?Как мне векторизовать функцию?

difftime2string <- function (x) { 
    if (abs(x) < 1) return(sprintf("%.2fms",x*1000)) 
    if (abs(x) < 100) return(sprintf("%.2fsec",x)) 
    if (abs(x) < 6000) return(sprintf("%.2fmin",x/60)) 
    if (abs(x) < 108000) return(sprintf("%.2fhrs",x/3600)) 
    if (abs(x) < 400*24*3600) return(sprintf("%.2fdays",x/(24*3600))) 
    sprintf("%.2fyears",x/(365.25*24*3600)) 
} 

EDIT: я имею в виду без Vectorize - как я пишу vectorised код со многими if с.

+5

'v <- Vectorize (difftime2string)'? – Justin

+0

Другой DateTime WTF. Вы знаете, что нет 365 (или 365,25) дней в году? В то время как Джош дал точный ответ на ваш вопрос, я настоятельно рекомендую вернуть полную строку DateTime и затем фильтровать такие вещи, как (псевдофункция) 'if (yearpart (string)! = 0) {print using" years "}' и так на. –

+1

P.S. Как насчет использования 'switch'? –

ответ

13
difftime2string <- function(x) { 
    breaks <- c(0, 1, 100, 6000, 108000, 400*24*3600, Inf) 
    units <- c("ms", "sec", "min", "hrs", "days", "years") 
    fact <- c(1000, 1, 1/60, 1/3600, 1/(24*3600), 1/(365.25*24*3600)) 
    ii <- findInterval(x, breaks) 
    sprintf(paste0("%.2f", units[ii]), x*fact[ii]) 
} 

x <- c(.1, 2, 200, 6001, 109000, 500*24*3600) 
difftime2string(x) 
# [1] "100.00ms" "2.00sec" "3.33min" "1.67hrs" "1.26days" "1.37years" 
+3

До тех пор, пока мы используем sprintf, почему бы нет: 'sprintf ("%. 2f% s ", x * fact [ii], units [ii])' – Dason

+0

Использование 'cut (x, breaks, labels = units, right = FALSE) 'избегает подмножества в конце. – Roland

+3

@Roland: это правда, но 'cut' будет намного медленнее, чем' findInterval' ... поэтому он может не стоить с точки зрения производительности. –

9

Самый простой способ сделать что-то подобное с нулевой мысли просто использовать Vectorize

difftime2stringVect <- Vectorize(difftime2string) 
+0

+1 Спасибо за ваш ответ! – sds

Смежные вопросы