2014-01-14 6 views
0

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

Вот некоторые фиктивные данные. Скажем, x и y - это стороны прямоугольника и z какой-то идентификатор. В действительности, они не известны заранее, но выводятся функцией. Реальная функция принимает каталог видов в качестве аргумента, читает шейп-файлы, объединяет многоугольники и делает кучу других вещей, но выводит площадь поверхности. Для каждого вида (т. Е. Запуска функции) я хотел бы сохранить каждую выделенную область в матрице или в кадре данных для дальнейшего анализа, а не выводить его на отдельные переменные.

myfunc <- function(x, y, z){ 
    area <- x*y 
    id <- z 
    tmp <- cbind(area,id) 
    assign(as.matrix('mtrx'), rbind(tmp), envir=.GlobalEnv) 

} 

Вышеупомянутое, очевидно, создает только матрицу и перезаписывает ее каждый раз, когда функция запускается.

Любые указатели были бы очень признательны!

+0

Первым аргументом должно быть имя объекта для присвоения. Почему вы преобразовываете строку в матрицу символов? Работает ли это 'assign ('mtrx', ....)'? –

+0

Матрица 'mtrx' создается после запуска функции ... –

+1

ОК, но моя точка является первым аргументом' assign' - символьным вектором имени, которому вы хотите присвоить вещь, а не матрицы. Прочитайте '? Assign'. –

ответ

1

Вот основная идея.

myfunc <- function(ID) { 
    # do a bunch of stuff based on ID 
    # calculate area 
    area <- 2*ID + rnorm(1,0,10) # fake the area... 
    return(c(ID=ID,area=area)) 
} 

ID.list <- rep(1:100) # list of ID's 
result <- do.call(rbind,lapply(ID.list,myfunc)) 
# head(result) 
#  ID  area 
# [1,] 1 -14.794850 
# [2,] 2 13.777036 
# [3,] 3 17.807578 
# [4,] 4 21.070712 
# [5,] 5 11.904047 
# [6,] 6 3.735771 

Возвращение ID и area как именованный вектор с c(ID=ID, area=area). Сделайте это для всех ID с вызовом lapply(...). Затем свяжите их все вместе, используя do.call(rbind,...).

+0

@jihoward: Спасибо, что комментировали. Ах, да, это похоже на хороший подход! Ура! –

1

Я очень рекомендую против этот метод, но вы должны использовать get в этой последней строке

assign('mtrx', rbind(get('mtrx', envir=parent.frame()), tmp)), envir=.GlobalEnv) 
+0

Спасибо за комментарий. Почему причины для рекомендации против него? Функция, которую я имею в действительности, - это слияние многоугольников (распределение видов) и вычисление площади поверхности. Входным аргументом является вид. Я просто хочу поместить все вычисленные области в одну матрицу или фрейм данных для дальнейшего анализа. –

+3

Очевидной альтернативой назначению в другую среду является переход матрицы вперед. Причина рекомендации против метода присваивания заключается в том, что из-за того, что не передается матрица, мало что получается, в то время как существует большая уязвимость для ошибок и ошибочных результатов. Это относительно безвредно, предполагая, что ваш код - всего несколько простых строк, но даже тогда это вводит излишнюю сложность в коде. Другими словами, я не могу придумать ни одной веской причины для этого, но могу думать о многих плохих причинах, чтобы не делать этого. –

2

Если, как в вашем примере, вы знаете значения x, y и z в заранее, имеет смысл сказать что-то вроде:

> f1 <- function(x, y, z) c(x*y, z) 
mapply(f1, x=seq(4), y=seq(4), z=seq(4)) 

>  [,1] [,2] [,3] [,4] 
[1,] 1 4 9 16 
[2,] 1 2 3 4 

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

Вы говорите

новая строка со значениями добавляется

, но в памяти новая матрица создана (assign ред) с новой строки добавляется каждый раз, когда вы добавляете. (Вы находитесь в Circle 2). Для данных небольшого размера это вряд ли будет проблемой на практике.

Кроме того, при использовании функции assign может возникнуть неудобство при вызове функции в среде (например, в другой функции), поэтому, как правило, лучше избегать, если это возможно. Обычно есть лучшая альтернатива.

+1

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

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