2012-05-07 1 views
1

Недавно я начал экспериментировать с R как языком, используемым для генетического программирования. Я медленно, но уверенно все больше узнал о том, как работает R, и о его лучших методах кодирования. Тем не менее, я попал в дорожный блок. Вот моя ситуация. У меня есть набор данных с примерно 700 строк, каждая строка содержит 400 столбцов. У меня есть все настройки, чтобы функция с несколькими параметрами была такой же, как количество столбцов, отправляемых в качестве параметра в функцию оценки оценки (пригодности). Я хочу перейти по строке в наборе данных и передать значения в каждом столбце строки в оцениваемую функцию. Первой проблемой было выяснение того, как передавать параметры отдельно в функцию. Под «отдельно» я имею в виду, что функция ожидает 400 параметров, а не вектор длины 400. Для этого я использовал следующее:Функция, векторы и петли в R

do.call(function,as.list(parameters)) 

Где параметры вектор месяца переменного (1-12) следует, что добавляется к значениям в строке в наборе данных. Это работает отлично, я просто использовал цикл for для итерации по 700 строкам в наборе данных, а затем еще один цикл в течение 12 месяцев и использование выше для накопления вектора выходов. Проблема в том, что это очень медленно, около 24-28 секунд на каждую функцию. И у меня есть 100-500 функций, посланных в эту оценку каждое поколение эволюции. Суть в том, что это не путь. Затем я попытался использовать метод sapply, как показано ниже.

outputs <- sapply(1:12,function(m) sapply(rows[1:length(rows)],function(p) do.call(f,as.list(c(p,m))))) 

Это применяется (1-12), как месяцы и затем применяется (1-700) в качестве строк набора данных. Это заняло не меньше времени. Любые идеи по решениям будут полезны.

+0

Вы считали использование функции 'ddply' из пакета' plyr'? –

+2

Вы можете использовать 'Rprof', чтобы определить, какие части вашего кода являются самыми медленными. –

+0

Я взглянул на plyr. Как это будет реализовано? У меня есть список векторов, каждый вектор - строка, содержащая параметры. Мне нужно отправить каждую строку в функцию вместе с переменной месяца. –

ответ

6

Основная проблема в таких случаях, как это обычно, что подход, который вы принимаете, является неправильным. Я не знаю достаточно о вашем конкретном случае, но:

  1. Try векторизовать расчеты - так что ваша функция должна работать на ВСЕХ строк, а не только один на один раз.
  2. Если вы просто сохраняете числа в data.frame, преобразование его в матрицу обычно ускоряет многие операции.
  3. Не записывайте функции, которые принимают 400 параметров! 5, вероятно, тоже на высокой стороне.

EDIT Поскольку вы создаете функцию, вы должны быть в состоянии генерировать вместо другой версии, которая принимает вектор значений вместо того, что по многим параметрам. Заметим, что вектор вы передаете его могут иметь имена:

# Convert this: 
f <- function(foo, bar) { 
    foo+bar 
} 
do.call(f, list(foo=42, bar=13)) 

# To this: 
f <- function(args) { 
    args[["foo"]] + args[["bar"]] 
    # or even faster: 
    #args[[0]] + args[[1]] 
    # or fastest: 
    #sum(args) 
} 
do.call(f, list(args=c(foo=42, bar=13))) 
# or, simply 
f(c(foo=42, bar=13)) 

... вызов функции с 1 параметром вместо 400 составляет около 60x быстрее! Но обратите внимание, что это просто накладные расходы на вызов функции. Вам нужно измерить, сколько времени занимает действительная функция. Если это занимает второе или большее число, то не имеет значения, насколько эффективно вы это называете или насколько эффективны ваши петли ...

+0

@ Исаак Драчманн: Я согласен с Томми, вам нужно рассказать нам больше о вашем коде, чтобы получить больше помощи, чем общие рекомендации. – cbeleites

+1

Дополнение к пункту 2 Томми: data.frames могут содержать матрицы в своих столбцах. Поэтому, даже если все 400 параметров не одного типа, вы можете сгруппировать их в несколько матриц. Вы можете даже ссылаться на эти столбцы в формулах так же, как вы укажете «нормальные» столбцы. – cbeleites

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

  • Нет связанных вопросов^_^