Как избежать нескольких циклов с несколькими переменными в R

У меня есть два набора данных, хранящихся в таблицах, один набор [a, b] а другой [x, Sx, y, Sy, rho], У меня есть функция вероятности f что требует (a, b, x, Sx, y, Sy, rho), В конце я хочу найти сумму вероятностных результатов по всем [x, Sx, y, Sy, rho] для первого [a, b], Затем найдите сумму для всех [x, Sx, y, Sy, rho] над вторым [a, b], так далее...

Я хотел бы иметь несколько сотен строк в [x, Sx, y, Sy, rho] файл и несколько сотен тысяч строк в [a, b] файл.

Мне интересно, есть ли способ сделать это без использования двух циклов? Я попробовал следующее, и это не совсем работает так, как я хочу, но я знаю, что это будет слишком медленно.

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

# data  file with (a, b)
data            <- matrix( c(1, 0, 1, 1, 0.5, 0), nrow=3, ncol=2) 
colnames(data)  <- c("a", "b") 
Ndat            <- dim(data)
Ndata           <- Ndat[1]

# data2 file with (x, Sx, y, Sy, rho)
data2           <- matrix( c(1, 0.1, 1, 0.1, 0.002, 2, 0.1, 2, 0.1, 0.000001, 
                             2, 0.1, 1, 0.1, 0.002), nrow=3, ncol=5) 
colnames(data2) <- c("x", "Sx", "y", "Sy", "rho") 
Ndat2           <- dim(data)
Ndata2          <- Ndat[1]

# function requires variables (a, b, s, Sx, y, Sy, rho) 
Prob  <- function(a, b, Xi, sX, Yi, sY, rho) {sqrt(1 + a ^ 2) * (
  exp(-((b + a * Xi - Yi) ^ 2 / (
    2 * ((a ^ 2 * sX ^ 2) - 
         (2 * a * rho * sX * sY) + sY ^ 2)))) * sqrt((
           1 - rho ^ 2) / (
             a ^ 2 * sX ^ 2 - 2 * a * rho *sX *sY + sY ^ 2))/(
               sqrt(2 * pi) * sqrt(1 - rho ^ 2)))
    }

# Here is my weak attempt
Table <- NULL
Table <- for (j in 1:Ndata) { 
   sum (for (i in 1:Ndata2) {
   Datatable[i] = Prob(data[j, a], data[j, b], data2[i, x], 
                 data2[i, Sx], data2[i, y], data2[i, Sy], 
                 data2[i, rho])
   })
}

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

Вероятно, есть лучший способ определить число или строки в data получить Ndata как глобальный, но это первые, на которые я наткнулся.

Функция не должна быть рекурсивной, но теперь я вижу, что это так, как я ее написал. Я потратил много часов на вводные уроки для R и до сих пор очень трудно понять, как apply Набор функций лучше всего реализован.

Я хотел бы одну итерацию, чтобы применить эту функцию к каждой строке в data2 с помощью a, b из первого ряда data, затем sum вероятность для всех тех. Тогда следующая итерация должна суммировать все вероятности для строки 2 data с помощью a, b применяется к каждому ряду data2

1 ответ

У меня есть ощущение, что есть более простой способ сделать это, но что-то вроде этого, вероятно, сработает.

f <- function(a,b,x,y,z) a+b+x+y+z
f.new <- function(p1,p2) {
  p1=as.list(p1); p2=as.list(p2)
  f(p1$a,p1$b,p2$x,p2$y,p2$z)
}

data1 <- data.frame(a=1:10,b=11:20)
data2 <- data.frame(x=1:5,y=21:25,z=31:35)
indx  <- expand.grid(indx2=seq(nrow(data2)),indx1=seq(nrow(data1)))
result <- with(indx,f.new(data1[indx1,],data2[indx2,]))
sums   <- aggregate(result,by=list(rep(seq(nrow(data1)),each=nrow(data2))),sum)

Вы, кажется, хотите оценить функцию для каждой комбинации двух наборов переменных, набор (a,b) и множество (x, Sx, y, Sy, rho), затем суммируйте по второму набору для каждого экземпляра первого набора.

Итак, сначала это переопределяет функцию f(...) принять два аргумента, представляющих два набора. Это f.new(...), Вероятно, вам следует определить исходную функцию таким образом - она ​​будет работать быстрее.

Затем мы создаем фрейм данных, indx который имеет два столбца, представляющих каждую комбинацию номеров строк в data1 а также data2, тогда мы называем f.new(...) с помощью data1 а также data2 индексируется с помощью indx, Это производится result которая имеет функцию, оцениваемую при каждой комбинации (a,b) а также (x,y,z), Затем мы собираем это, чтобы получить указанные вами суммы.

Этот подход требует большого объема памяти; result будет иметь ~ 10 мм элементов, но будет работать быстрее, чем циклы.

Другие вопросы по тегам