2015-05-16 21 views
6

Szukam sposobu na manipulowanie wieloma kolumnami w data.table w R. Ponieważ muszę dynamicznie adresować kolumny, jak również drugie wejście, nie byłem w stanie Znajdź odpowiedź.Zmiana wielu kolumn w data.table r

Ideą jest indeksem dwa lub więcej serii w określonym terminie przez podzielenie wszystkich wartości przez wartości data np

set.seed(132) 
# simulate some data 
dt <- data.table(date = seq(from = as.Date("2000-01-01"), by = "days", length.out = 10), 
       X1 = cumsum(rnorm(10)), 
       X2 = cumsum(rnorm(10))) 

# set a date for the index 
indexDate <- as.Date("2000-01-05") 

# get the column names to be able to select the columns dynamically 
cols <- colnames(dt) 
cols <- cols[substr(cols, 1, 1) == "X"] 

Część 1: Easy data.frame/zastosować podejście

df <- as.data.frame(dt) 
# get the right rownumber for the indexDate 
rownum <- max((1:nrow(df))*(df$date==indexDate)) 

# use apply to iterate over all columns 
df[, cols] <- apply(df[, cols], 
        2, 
        function(x, i){x/x[i]}, i = rownum) 

Część 2: (szybko) data.table podejście dotychczas moja data.table podejście wygląda następująco:

for(nam in cols) { 
    div <- as.numeric(dt[rownum, nam, with = FALSE]) 
    dt[ , 
    nam := dt[,nam, with = FALSE]/div, 
    with=FALSE] 
} 

szczególnie wszystkie with = FALSE nie wyglądają zbyt dobrze.

Czy znasz jakiś szybszy/bardziej elegancki sposób wykonania tej operacji?

Każdy pomysł jest bardzo doceniany!

Odpowiedz

8

Jedną opcją byłoby użycie set, ponieważ dotyczy to wielu kolumn. Zaletą korzystania z funkcji set jest uniknięcie narzutu na wartość [.data.table i przyspieszenie.

library(data.table) 
for(j in cols){ 
    set(dt, i=NULL, j=j, value= dt[[j]]/dt[[j]][rownum]) 
} 

Albo nieco wolniej rozwiązaniem byłoby

dt[, (cols) :=lapply(.SD, function(x) x/x[rownum]), .SDcols=cols]