2014-11-07 2 views
3

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

Мне показалось, что я знаком с lapply, mapply и т. Д. Но, возможно, этого недостаточно.

В качестве простого примера:

> a<-matrix(1:100,ncol=10); 
> a 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 1 11 21 31 41 51 61 71 81 91 
[2,] 2 12 22 32 42 52 62 72 82 92 
[3,] 3 13 23 33 43 53 63 73 83 93 
[4,] 4 14 24 34 44 54 64 74 84 94 
[5,] 5 15 25 35 45 55 65 75 85 95 
[6,] 6 16 26 36 46 56 66 76 86 96 
[7,] 7 17 27 37 47 57 67 77 87 97 
[8,] 8 18 28 38 48 58 68 78 88 98 
[9,] 9 19 29 39 49 59 69 79 89 99 
[10,] 10 20 30 40 50 60 70 80 90 100 

Скажем, я хочу, чтобы применить функцию к каждой строке, я хотел бы сделать:

apply(a, 1, myFunction); 

Однако моя функция принимает аргумент, так:

apply(a, 1, myFunction, myArgument); 

Но если я хочу, чтобы мой аргумент принимал другое значение для каждой строки, я не могу найти правильный способ сделать это. Если я определяю «myArgument» с несколькими значениями, весь вектор, очевидно, будет передаваться каждому вызову «myFunction».

Я думаю, что мне понадобится гибрид между применением и многомерным mapply. Имеет ли это смысл ?

Один «грязный» способ достижения своей цели, чтобы разбить матрицу по строкам (или столбцов), используйте mapply на результирующий список и объединить результат обратно в матрицу:

do.call(rbind, Map(myFunction, split(a,row(a)), as.list(myArgument))); 

Я имел посмотрите на развертку, совокупность, все * примените варианты, но я бы не нашел идеального соответствия с моей потребностью. Я пропустил это?

Благодарим за помощь.

ответ

1

Вы можете использовать sweep для этого.

a <- matrix(rnorm(100),10) 
rmeans <- rowMeans(a) 
a_new <- sweep(a,1,rmeans,`-`) 
rowMeans(a_new) 
+0

Похоже, я не очень проснулся, когда попробовал. Ваше предложение, чтобы посмотреть на него, сделало мой день. Спасибо, и жаль насчет «наивного» вопроса. Надеюсь, это поможет кому-то еще позже. –

+0

После дальнейших испытаний я помню, почему развертка не сделала работу. Фактически, в отличие от «применить» функция «развертка» будет вызывать только функцию FUN один раз, передавая ей исходную матрицу и матрицу со значениями, построенными из аргументов STAT и MARGIN. Предполагается, что функция FUN выполнит операцию «по ячейке» на матрицах. То, что я хотел бы достичь, - это вызов «myFunction» для каждой строки (или столбца) исходной матрицы. Чтобы быть ясным, подходящий пример состоит в применении окна сглаживания с разным размером в каждой строке. –

0

Я не думаю, что есть какие-либо большие ответы, но вы можете несколько упростить решение с помощью mapply, который обрабатывает «rbind» часть для вас, предполагая, что ваша функция всегда возвращает один и тот же вектор размер (также , Map действительно просто mapply):

a <- matrix(1:80,ncol=8) 
myFun <- function(x, y) (x - mean(x)) * y 
myArg <- 1:nrow(a) 

t(mapply(myFun, split(a, row(a)), myArg)) 
0

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

# Original matrix 
a <- matrix(runif(n=100), ncol=5) 
# Different value for each row 
v <- runif(n=nrow(a)) 
# Result matrix -> Add a column with the row number 
o <- cbind(1:nrow(a), a) 
fun <- function(x, v) { 
    idx <- 2:length(x) 
    i <- x[1] 
    r <- x[idx]/v[i] 
    return(r) 
} 
o <- t(apply(o, 1, fun, v=v) 

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