2013-02-19 3 views
1

У меня есть код, который идентифицирует выбросы в фрейме данных, а затем либо удаляет, либо закрывает их. Я пытаюсь ускорить процесс удаления с помощью функции apply() (или, возможно, другого метода).подмножество быстро по многим столбцам

Пример данных

https://github.com/crossfitAL/so_ex_data/blob/master/subset 
# this is the contents of a csv file, you will need to load it into your R session. 

# set up an example decision-matrix 
# rm.mat is a {length(cols) x 4} matrix -- in this example 8 x 4 
# rm.mat[,1:2] - identify the values for min/max outliers, respectively. 
# rm.mat[,3:4] - identify if you wish to remove min/max outliers, respectively. 
cols <- c(1, 6:12) # specify the columns you wish to examine 
rm.mat <- matrix(nrow = length(cols), ncol= 4, 
       dimnames= list(names(fico2[cols]), 
       c("out.min", "out.max","rm outliers?", "rm outliers?"))) 

# add example decision criteria 
rm.mat[, 1] <- apply(fico2[, cols], 2, quantile, probs= .05) 
rm.mat[, 2] <- apply(fico2[, cols], 2, quantile, probs= .95) 
rm.mat[, 3] <- replicate(4, c(0,1)) 
rm.mat[, 4] <- replicate(4, c(1,0)) 

Вот мой текущий код Подменю:

df2 <- fico2 # create a copy of the data frame 
cnt <- 1  # add a count variable 
for (i in cols) { 
# for each column of interest in the data frame. Determine if there are min/max 
# outliers that you wish to remove, remove them.   
    if (rm.mat[cnt, 3] == 1 & rm.mat[cnt, 4] == 1) { 
    # subset/remove min and max outliers 
    df2 <- df2[df2[, i] >= rm.mat[cnt, 1] & df2[, i] <= rm.mat[cnt, 2], ] 
    } else if (rm.mat[cnt, 3] == 1 & rm.mat[cnt, 4] == 0) { 
    # subset/remove min outliers 
    df2 <- df2[df2[, i] >= rm.mat[cnt, 1], ] 
    } else if (rm.mat[cnt, 3] == 0 & rm.mat[cnt, 4] == 1) { 
    # subset/remove max outliers 
    df2 <- df2[df2[, i] <= rm.mat[cnt, 2], ] 
    } 
    cnt <- cnt + 1 
} 

Предлагаемое решение: Я думаю, что я должен быть в состоянии сделать это с помощью типа применяются функции, с удалением цикла for/vectorization, ускоряющего код. Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь применить функцию if-and-only-if, что матрица решений указывает, что я должен. IE - с использованием логического вектора rm.mat[,3] or rm.mat[,4], чтобы определить, следует ли подмножество "[" применять к кадру данных df2.

Любая помощь у вас была бы принята с благодарностью! Также, пожалуйста, дайте мне знать, достаточно ли примеров данных/кода.

+4

Привет Алекс, Просто предложение: я думаю, было бы более полезно, если бы вместо того, чтобы публиковать, как вы очищаете данные, вместо этого просто разместите образец своих данных (или удаленный симулятор). –

+0

@ RicardoSaporta - не мои фактические данные. Это некоторые примеры из класса Coursera. Мои данные большие и тусклые. Я думал, это будет проще. –

+1

@Alex, I второе предложение РикардоСапорта, что было бы лучше, если бы вы переделали свою проблему **, сосредоточившись только на ней без особого введения. Я пытаюсь читать в третий раз! В вашем коде нет комментариев. Вы ожидаете, что люди будут смотреть на код и понимать ... Я не думаю, что многие люди попытаются ответить. – Arun

ответ

0

Здесь есть решение. просто для уточнения кода. Надеюсь, что другие могут использовать его, чтобы дать лучшее решение.

Так что, если разобраться, у вас есть решение матрицы, которая выглядит следующим образом:

rm.mat 
             c1 c2 c3 c4 
amount.funded.by.investors  27925.000 NA 0 1 
monthly.income     11666.670 NA 1 0 
open.credit.lines     18.000 NA 0 1 
revolving.credit.balance  40788.750 NA 1 0 
inquiries.in.the.last.6.months  3.000 NA 0 1 
debt.to.inc      28.299 NA 1 0 
int.rate       20.490 NA 0 1 
fico.num       775.000 NA 1 0 

И вы пытаетесь фильтровать большую матрицу в соответствии со значениями этой матрицы

colnames(rm.mat) <- paste('c',1:4,sep='')  
rm.mat <- as.data.frame(rm.mat) 
apply(rm.mat,1,function(y){ 
    h <- paste(y['c3'],y['c4'],sep='') 
    switch(h, 
      '11'= apply(df2,2, function(x) 
           df2[x >= y['c1'] & x <= y['c2'],]), ## we never have this!! 
      '10'= apply(df2,2, function(x) 
           df2[x >= y['c1'] , ]), ## here we apply by columns! 
      '01'= apply(df2,2,function(x) 
           df2[x <= y['c2'], ])) ## c2 is NA!! so !!! 
} 
) 
+0

Ваш 'rm.mat' - это не то, что у меня есть. 'Гт.mat [, 1] <- apply (fico2 [, cols], 2, quantile, probs = .05) rm.mat [, 2] <- apply (fico2 [, cols], 2, quantile, probs = .95) '. Я думаю, что ваше решение может сработать ... Я собираюсь вернуться к нему сегодня вечером. Я не знаком с использованием 'switch()'. Благодаря! –

+1

@Alex мое решение действительно показать вам, что, прежде чем думать производительность, вы ДОЛЖНЫ писать ЧИСТЫЙ и READABLE код! После этого вы можете настроить его! taht сказал, что это действительно удобная функция, когда у вас много условий. – agstudy

+0

Я согласен с вами. A) Я все еще улучшаю свое кодирование R; но B) Я думаю, что это больше связано с попыткой предоставить короткий и относительно простой пример из 1 части функции, которая имеет 200 строк кода ... что я действительно ДЕЙСТВИТЕЛЬНО оцениваю вас, а остальные на этом посту , не тратя время на это, несмотря на разочарование. –

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