【问题标题】:Recalculate each point in dataframe with lapply/sapply使用 lapply/sapply 重新计算数据框中的每个点
【发布时间】:2011-04-05 08:50:42
【问题描述】:

我编写了自己的名为 batcheffect 的函数来重新计算数据框中的所有值。 该函数只需要数据框作为导入。首先,在函数中计算平均值,然后对数据框中的每个点进行计算并创建一个新的数据框。

batcheffect <- function (experiment){    
   corr<-list()    
   matrixexp<-as.matrix(experiment)    
   expmean <-mean(matrixexp)

   for (i in 1:length(matrixexp)){    
      correction <- (matrixexp[i]-overallmean - expmean)+overallmean    
      corr[[i]]<- matrix(correction)
   }
   return(unlist(corr)) 
}

对于大型数据帧,函数内的循环很慢。所以我想使用 sapply 或 lapply 函数来加速这个过程。有人给点建议吗?

谢谢

更新: 例如我有一个这样的数据框 df

计算数据框中所有值的平均值。数据帧被转换为矩阵 df1

数据的第一个目标是通过列名生成子集。您生成三个组,A 组,B 组和 C 组。子集由以下代码定义:

"selectexperiments" <- function (partialname, data) 
{
result <- data[,grep(partialname, colnames(data))]
return(result)
}
A<-selectexperiments('A', df)
B<-selectexperiments('B', df)
C<-selectexperiments('C', df)

创建了三个组。对于例如组 A 中的每个值,我想计算以下总和: (值 - 总体均值 - 组的均值)+ 总体均值。 因此我创建了这个批处理效果函数。

"batcheffect" <- function (group)
{
corr<-list()
matrixexp<-as.matrix(group)
expmean <-mean(matrixexp) #mean of the group
for (i in 1:length(matrixexp)){ 
correction <- (matrixexp[i]-overallmean - expmean)+overallmean
corr[[i]]<- matrix(correction)
}
return(unlist(corr))
}

Abatch<-batcheffect(A)

结果现在可以了,但是我会将结果作为数据框返回。对于我自己的数据,这个功能真的很慢,所以我认为可能有一种加速方法,比如 sapply 的东西。

【问题讨论】:

  • 您能否举一个示例数据框,并解释一下overallmean的来源?
  • @csgillespie :请不要在问题中编辑代码。编辑时不应该“优化”代码。这可能会导致完全混乱。
  • @Joris:对不起,我的错。我不是要更改代码,只是缩进它。我不小心删除了(如您所见)as.matrix 行。我想你对“代码格式”没有问题?
  • @csgillespie :格式没问题,我只注意到它已经消失了,因为 Richie 对我的回答发表了评论。

标签: r dataframe lapply


【解决方案1】:

你的功能很奇怪。可以简化为:

batcheffect <- function (experiment){
    matrixexp<-as.matrix(experiment)
    expmean <-mean(matrixexp)
    c(matrixexp - expmean)
}

并且会给出完全相同的结果。简单的微积分表明

(matrixexp[i]-overallmean - expmean)+overallmean

完全等于

matrixexp[i]- expmean

并且由于 R 计算是矢量化的,因此不需要循环。它返回一个向量(因此是 c() 函数)。

使用unlist(),您可以进一步简化为:

batcheffect2 <- function(experiment){
  x <- unlist(experiment,use.names=F)
  x - mean(x)
}

再次返回完全相同的结果。你确定这是你的想法吗?


编辑:

鉴于您的 cmets,我在此处添加测试代码。我将您的原始函数命名为old.batcheffect()。如您所见,在示例数据帧上(在初始化神秘overallmean 之后)所有函数的结果都是相同的:

> Df <- data.frame(A1=1:10,B1=10:1,C1=11:20)
> overallmean <- runif(1)
> X1 <- old.batcheffect(Df)
> X2 <- batcheffect(Df)
> X3 <- batcheffect2(Df)

> all.equal(X1,X2)
[1] TRUE
> all.equal(X2,X3)
[1] TRUE

EDIT2:

要获得返回原始数据帧的批处理效果,您只需要一行代码:

batcheffect <- function(x) x - mean(unlist(x))

您现在可以在一个函数中处理完整的原始数据帧:

summaryBatch <- function(data,groups){
    tmp <- lapply(groups,function(x){
        data[,grep(x,names(data))]
    })
    out <- lapply(tmp,function(x){
        x - mean(unlist(x))

    })
    do.call(cbind,out)
}

然后:

summaryBatch(df,c("A","B","C"))

返回一个包含所有列的数据框,其中每列减去组平均值。如前所述,您可以添加并随后删除总体均值,但这根本没有区别。

【讨论】:

  • 是的,这就是我的意思,但是,现在您创建了一个包含值的列表。要将其转换为数据框,这些值并不合适。 c(matrixexp - expmean) 垂直读取,unlist() 函数横向替换。你知道我的意思吗?
  • @Lisann :我得到了两次完全相同的向量。如果我在全局中设置了一个整体平均值,例如 20,我会得到与所有三个函数完全相同的向量。所以我不明白你的意思,这些函数完全相同。除非您的实验不是偏离路线的数据框...
  • @Lisann :顺便说一句,unlist() 也可以垂直工作。试试下面的代码看看:Df &lt;- data.frame(A=1:10,B=10:1,C=11:20) ; all.equal(unlist(Df,use.names=F),c(as.matrix(Df)))
  • 更多奇怪的东西:matrixexpoverallmean 被函数使用但没有在那里定义。这意味着您的函数的行为取决于其他环境的状态(例如,您是否在用户工作区中定义了这些变量)。这总是会导致代码错误。
  • 我的实验不行!它垂直计算每个值并将其水平放回。有办法改变吗?
猜你喜欢
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 2020-11-30
  • 2018-07-28
  • 2021-08-19
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多