2010-08-24 4 views
6

Я использую R, и у меня есть два data.frames, A и B. Они оба имеют 6 строк, но A имеет 25000 столбцов (генов), а B имеет 30 столбцов. Я хотел бы применить функцию с двумя аргументами f(x,y), где x - каждый столбец A и y - это каждый столбец B. До сих пор это выглядит следующим образом:Применить к двум кадрам данных

i = 1 
for (x in A){ 
    j = 1 
    for (y in B){ 
     out[i,j] <- f(x,y) 
     j = j + 1 
    } 
    i = i + 1 
} 

У меня есть две проблемы с этим: из моего программирования Python Я ассоциирую отслеживании счетчиков, как это как crufty, и от моего R программирования я нервничаю из за петли. Однако я не могу понять, как применить apply (или даже если я должен применить apply) к этой проблеме и надеялся, что кто-то может просветить меня. Мне нужно обработать f() как атомный (это на самом деле cor.test()).

+0

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

+1

Я не решаюсь предложить что-либо, так как я очень новый пользователь R, но у меня был хороший успех, используя пакет plyr для обработки данных. http://had.co.nz/plyr/ – dnagirl

ответ

6

Поскольку вы используете фреймы данных, это может быть быстрее использовать lapply или sapply, чтобы сделать это (особенно учитывая масштаб ваших кадров данных). Например,

x <- data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), col3=c(9,10,11,12)) 
y <- data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8)) 
bl <- lapply(x, function(u){ 
    lapply(y, function(v){ 
     f(u,v) # Function with column from x and column from y as inputs 
    }) 
}) 
out = matrix(unlist(bl), ncol=ncol(y), byrow=T) 
1

Вложенные приложения применяются, но не самый простой синтаксис.

x<-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), col3=c(9,10,11,12)) 
y<-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8)) 

z<-apply(x,2,function(col,df2) 
      { 
       apply(df2,2,function(col2,col1) 
          { 
           col2+col1 
          },col) 
      },y) 

z 
col1 col2 col3 
[1,] 2 6 10 
[2,] 4 8 12 
[3,] 6 10 14 
[4,] 8 12 16 
[5,] 6 10 14 
[6,] 8 12 16 
[7,] 10 14 18 
[8,] 12 16 20 
+0

Итак, первый аргумент 'function()' всегда тот, который указан в приложении apply, тогда вы предоставляете второй как дополнительный аргумент. Благодаря! Синтаксис в порядке в нотации вопроса: 'apply (A, 2, function (a, B) {apply (B, 2, f, a)}, B)' , но все же намного сложнее читать, чем писать? Я думаю, мне пришлось бы написать обертку, если f (a, b) не была симметричной ... –

2

Некоторые данные

nrows <- 6 
A <- data.frame(a = runif(nrows), b = runif(nrows), c = runif(nrows)) 
B <- data.frame(z = rnorm(nrows), y = rnorm(nrows)) 

Хитрость: помните столбцы с expand.grid

counter <- expand.grid(seq_along(A), seq_along(B)) 
f <- function(x) 
{ 
    cor.test(A[, x["Var1"]], B[, x["Var2"]])$estimate 
} 

Теперь нам нужно только 1 вызов apply.

stats <- apply(counter, 1, f) 
names(stats) <- paste(names(A)[counter$Var1], names(B)[counter$Var2], sep = ",") 
stats 

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

  • Нет связанных вопросов^_^