Как избежать нескольких циклов с несколькими переменными в 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 мм элементов, но будет работать быстрее, чем циклы.