【问题标题】:Apply over two data frames应用于两个数据框
【发布时间】:2011-04-03 05:27:13
【问题描述】:

我正在使用 R,并且我有两个 data.frames,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())。

【问题讨论】:

  • 取决于f,这听起来类似于内积。我知道使用外积可以指定要使用的函数,但不知道如何为内积执行此操作。
  • 我是一个非常新的 R 用户,所以我不愿提出任何建议,但我使用 plyr 包进行数据操作取得了很好的成功。 had.co.nz/plyr

标签: r apply


【解决方案1】:

一些数据

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

【讨论】:

    【解决方案2】:

    由于您使用的是数据帧,因此使用 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)
    

    【讨论】:

      【解决方案3】:

      嵌套 apply 是可行的,但不是最简单的语法。

      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
      

      【讨论】:

      • 所以function() 的第一个参数总是应用中引用的那个,然后你提供第二个作为附加参数。谢谢!问题的符号中的语法是可以的:apply(A,2,function(a,B){apply(B,2,f,a)},B) 但仍然比写更难读?如果 f(a,b) 不是对称的,我想我必须编写一个包装器......
      猜你喜欢
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      • 2012-10-31
      相关资源
      最近更新 更多