2010-08-24 70 views
6

我使用R,并且我有两个数据帧,AB。它们都有6行,但A有25000列(基因),而B有30列。我想申请一个带有两个参数f(x,y)的函数,其中xA的每一列,而yB的每一列。到目前为止,它看起来像这样:应用两个数据帧

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编程,并从我的[R编程我紧张的for循环。但是,我不太明白如何申请apply(或者即使我应该申请apply)这个问题,并希望有人可以启发我。我现在需要将f()视为原子(实际上是cor.test())。

+0

根据'f',这听起来与内积类似。我知道外部产品你可以指定一个功能使用,但不知道如何去做内部产品。 – James 2010-08-24 15:19:09

+1

由于我是一个非常新的R用户,我毫不犹豫地提出任何建议,但我使用plyr软件包进行数据处理取得了很好的成功。 http://had.co.nz/plyr/ – dnagirl 2010-08-25 20:38:44

回答

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()'的第一个参数总是应用中引用的那个,然后你提供第二个参数作为附加参数。谢谢! (A,2,function(a,B){apply(B,2,f,a)},B)' 但仍然困难得多阅读比写?如果f(a,b)不是对称的,我想我必须写一个包装器... – 2010-08-24 15:12:23

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