Как применить функцию к многомерному массиву на основе его индексов

У меня есть 4-мерный массив, и я хочу заполнить слоты значениями, которые являются функцией входных данных. Путем поиска на форумах здесь я обнаружил, что функция «внешний» полезна для матриц 2x2, но не может применяться к общим многомерным массивам. Есть ли что-нибудь, что может сделать это в R более эффективно, чем следующий код?

K <- array(0,dim=c(2,2,2,2)) #dimensions will be much larger
for(x1 in 1:2)
{
  for(y1 in 1:2)
  {
    for(x2 in 1:2)
    {
      for(y2 in 1:2)
      {
        K[x1,y1,x2,y2] <- x1*y2 - sin(x2*y1) #this is just a dummy function.
      }   
    }
  }
}

Спасибо заранее за любую помощь.


person Rookatu    schedule 14.05.2012    source источник
comment
Извините, это для языка программирования R. Как видите, я здесь новенький, и я думаю, что испортил свой вопрос, поместив его не в нужное место или что-то в этом роде. Тем не менее, любая помощь будет оценена по достоинству!   -  person Rookatu    schedule 14.05.2012
comment
ОК, я добавил для вас тег r — это должно помочь привлечь внимание людей, знакомых с R, которые могли бы ответить на ваш вопрос.   -  person Paul R    schedule 14.05.2012
comment
сейчас нет времени, но вы можете взглянуть на пакет tensor, в котором есть единственная функция (tensor), которая обобщает outer на многомерные массивы... может потребоваться немного дурачиться, чтобы понять это правильно   -  person Ben Bolker    schedule 14.05.2012


Ответы (1)


Редактировать; Вот то, что я думаю, будет еще более быстрым решением. Предполагается, что вы предопределили K, как вы предложили. Он использует конструкцию K[] <- для вставки значений, рассчитанных в среде фрейма данных. Использование квадратных скобок в левой части задания сохраняет структуру K, и я думаю, что она и векторизована, и самодокументируема:

dfm <- expand.grid(x1=1:2,x2=1:2,y1=1:2,y2=1:2) 
K[] <- with(dfm, x1*y2 - sin(x2*y1 ) )

Первое предложенное решение: если вы можете создать data.frame или матрицу с индексами x1,x2,y1,y2 и значениями, вы можете использовать: K[cbind(index-vectors)] ‹-значения конструкции:

mtx<- data.matrix( expand.grid(x1=1:2,x2=1:2,y1=1:2,y2=1:2) )
K[mtx] <- apply(mtx, 1, function(x) x["x1"]*x["y2"] - sin(x['x2']*x['y1']) )
#----------------
> K
, , 1, 1

        [,1]       [,2]
[1,] 0.158529 0.09070257
[2,] 1.158529 1.09070257

, , 2, 1

          [,1]     [,2]
[1,] 0.09070257 1.756802
[2,] 1.09070257 2.756802

, , 1, 2

        [,1]     [,2]
[1,] 1.158529 1.090703
[2,] 3.158529 3.090703

, , 2, 2

        [,1]     [,2]
[1,] 1.090703 2.756802
[2,] 3.090703 4.756802
person IRTFM    schedule 14.05.2012