2014-12-19 2 views
0

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

Я хотел бы иметь несколько сот строк в файле [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

+0

Вы пытаетесь найти какую-то форму рекурсивного программирования? Ваша функция 'f' вызывает себя, но неясно, как она должна работать. – gung

ответ

0

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

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 будет иметь элементы ~ 10MM, но будет работать быстрее, чем циклы.

+0

Большое спасибо @jlhoward, я думаю, что это будет работать неплохо, однако я не могу заставить функцию 'f.new (...)' возвращать 'результаты'. Я думаю, что может быть проблема в том, что мои данные не форматируются чисто, в таблицах, где хранятся данные, есть другие переменные. Есть ли способ сообщить новой функции, где найти переменные, используя заголовки столбцов? Мне сложно понять, где и как вызываются переменные из наборов данных, которые вы создали здесь. – Jesse

Смежные вопросы