2014-07-16 4 views
0

Я борюсь с функциями типа «apply» в R. У меня есть матрица, и я хочу использовать элементы каждой строки матрицы, использовать пользователя -defined, чтобы сделать некоторые вычисления на основе ввода из матрицы и создать новую, которая сохранит результаты этих вычислений.Применить функцию, используя элементы из каждой строки матрицы

Я понял, как это сделать, когда функция возвращает только один выход

Так, например, предположим матрицу А и функцию, которая выполняет какой-то расчет.

> A=matrix(1:16,nrow=4) 
> A 
    [,1] [,2] [,3] [,4] 
[1,] 1 5 9 13 
[2,] 2 6 10 14 
[3,] 3 7 11 15 
[4,] 4 8 12 16 

> B=apply(A,1,FUN=function(x) x[1]**2+2*x[2]+x[3]*x[4]) 
> B 
[1] 128 156 188 224 

Что мне нужно, чтобы расширить это в том случае, когда выход является вектором более одних элементов, представьте себе, например, что я хочу, чтобы вычислить значение трех различных полиномов вместо одного, как в примере и снова получить матрицу 4 × 3, которая будет содержать вычисление этих трех многочленов.

В настоящее время я делаю это с циклом «для», который считывает данные по строкам, выполняет функцию и сохраняет результаты в новой матрице, но это очень медленно. Примером может служить:

A=matrix(1:16,nrow=4) 
A 
    [,1] [,2] [,3] [,4] 
[1,] 1 5 9 13 
[2,] 2 6 10 14 
[3,] 3 7 11 15 
[4,] 4 8 12 16 
calc=function(e1,e2,e3,e4){ 
    x1=e1*e2+3*e3*e4 
    x2=e4+e2+5*e3**2-e4 
    x3=e1*e2*e3*e4 
    return(c(x1,x2,x3)) 
} 

results=matrix(nrow=4,ncol=3) 

for (i in 1:4){ 
    k=calc(A[i,1],A[i,2],A[i,3],A[i,4]) 
    results[i,]=k 
} 

results 
    [,1] [,2] [,3] 
[1,] 356 410 585 
[2,] 432 506 1680 
[3,] 516 612 3465 
[4,] 608 728 6144 

Любые идеи о том, как я мог бы применить аналогичные операции к матрице, избегая «для» более чем приветствуется. (Я не привязан к применяемым пакетам)

+0

Если вы включите ваш 'for' цикл может легче понять, как переписать его с' apply'. – janos

+0

Я продлил результат – KGeor

ответ

3

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

calc=function(row){ 
    e1 = row[1]; e2 = row[2]; e3 = row[3]; e4 = row[4] 
    x1=e1*e2+3*e3*e4 
    x2=e4+e2+5*e3**2-e4 
    x3=e1*e2*e3*e4 
    return(c(x1,x2,x3)) 
} 

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

t(apply(A, 1, calc)) 
+0

Все отлично! Большое спасибо – KGeor

0
apply(A,1,FUN=function(x){ 
    y<-rep(NA,3) 
    y[1]=x[1]+1 
    y[2]=x[2]+x[3] 
    y[3]=x[4]/2 
    return(t(y)) 
    } 
    ) 

Это сработало для меня. Очевидно, отредактируйте функции для y [1], y [2], y [3], и если вы хотите больше 3, также отредактируйте строку y<-rep(NA,3)

2

Не уверен, если это поможет:

fun1 <- function(mat){ 
x1 <- mat[,1]*mat[,2]+3*mat[,3]*mat[,4] 
x2 <- mat[,4]+mat[,2]+5*mat[,3]**2-mat[,4] 
x3 <- mat[,1]*mat[,2]*mat[,3]*mat[,4] 
    cbind(x1,x2,x3) 
    } 
fun1(A) 
#  x1 x2 x3 
# [1,] 356 410 585 
# [2,] 432 506 1680 
# [3,] 516 612 3465 
# [4,] 608 728 6144 
Смежные вопросы