2013-06-03 2 views
5

Я часто разбираюсь с данными в форматах xts и часто должен их масштабировать (скажем, в какой-то момент 100). В настоящее время я делаю это с помощью функции, которая работает с использованием for-loop - однако это не кажется очень функциональным.шкалы столбцов объекта xts

Вот как я сделать это сейчас:

df1 <- data.frame(rnorm(100), runif(100), 1:100*rnorm(100)) 
dfx <- xts(df1, order.by = seq(as.Date("2001-01-01"), by='mon', length.out=100)) 

dfxColScl <- function(dfrm, pos=1, idx = 100) 
{ 
    scaledDF <- dfrm 
    for (i in 1:ncol(dfrm)) { 
     scaledDF[, i] <- dfrm[,i]/as.numeric(dfrm[pos, i]) * idx 
    } 
    return(scaledDF) 
} 

Есть некоторые умные apply функция типа, которая является R способ сделать это?

ответ

4

sweep может использоваться для разделения матрицы на строку.

dfx.scaled2 <- sweep(100*dfx, 2, dfx[1], "/") 
all.equal(dfx.scaled, dfx.scaled2) # same result as @Joshua 
#[1] TRUE 
+0

+1, круто - спасибо. – ricardo

+0

Ницца. Я предположил, что 'sweep' не будет работать без использования' coredata (dfx [1]) ', но внутренний вызов' array' позаботится об этом для вас. –

3

Вы можете использовать apply.daily. Обратите внимание, что вам все равно придется использовать coredata в строке, которую вы хотите разделить, поскольку операции xts/zoo всегда выравниваются по индексу перед выполнением операции.

dfx.scaled <- apply.daily(dfx, function(x) x/coredata(dfx[1,])*100) 
+0

+1, спасибо. поэтому, если это были ежемесячные данные, я бы использовал apply.monthly? – ricardo

+0

@ricardo: В вашем примере 'dfx' * был * ежемесячно и' apply.daily' работал. Он работает, потому что индекс для 'dfx' - Date. –

+0

Прошу прощения - я не пробовал, пока не спросил. Я выхожу из этого, что 'apply.daily' будет работать во всех случаях? – ricardo

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