R语言 在apply函数中使用值列表中的列特定值

bzzcjhmw  于 2022-12-25  发布在  其他
关注(0)|答案(1)|浏览(153)

我正在为scRNA-seq数据编写自己的标准化函数,因为许多软件包都假设您使用的是密度矩阵(我不想也不需要这样做)。如果你不知道这意味着什么,这不是一个问题。本质上,我希望能够有一个供应函数,将一列中的所有值除以一个特定于该列的值。所以为了达到这个目的,我提供了一个长度与数据框的列相同的值列表,然后应用其他转换,如果没有提供列表,则使用apply正在处理的列中的值的总和。有没有办法不用for循环就可以做到这一点?保持矢量化吗

# function to run in apply
pseudocount_log2p1_transform <- function(x, scale_factor = 10000, UMI.provided = NULL){
  if(is.null(UMI.provided)){
    counts <- sum(x)}else{
      counts <- UMI.provided
    }
  x <- (x+1)/counts
  x <- x/scale_factor
  return(log2(x))
}

# function which needs fixing
pavlab.normalize <- function(df, UMI = NULL){
  df.cols <- colnames(df)
  df.rows <- rownames(df)
  if( is.null(UMI)){
    df <- data.frame(apply(df,  MARGIN = 2, pseudocount_log2p1_transform))
  }else{
# this line needs to be modified, so its providing the column specific count value
    df <- data.frame(apply(df,  MARGIN = 2, pseudocount_log2p1_transform(UMI.provided=UMI)))
  }
  colnames(df) <- df.cols
  rownames(df)<- df.rows
  return(df)
}

# reproducible example
df.example <- data.frame( a = c(1,0,1,2),
b = c(5,6,8,5),
c = c(4, 5, 4,4) )

count.list <- c(5, 25, 18)

# how do I fix this....?
pavlab.normalize(df = df.example, UMI = count.list)
wvyml7n5

wvyml7n51#

在代码中,如果我们想将UMI的相应值应用于相应的列,代替使用仅在“df”的列上循环的apply,我们可以使用具有作为dfUMI的输入自变量的Map,因此它在数据中的列上循环。并且假设ncol(df)length(UMI)相同,则向量中的元素

pavlab.normalize <- function(df, UMI = NULL){
  df.cols <- colnames(df)
  df.rows <- rownames(df)
  if( is.null(UMI)){
    df <- data.frame(apply(df,  MARGIN = 2, pseudocount_log2p1_transform))
  }else{
#
   df[] <- Map(pseudocount_log2p1_transform, df, UMI.provided = UMI)
  
  }
  colnames(df) <- df.cols
  rownames(df)<- df.rows
  return(df)
}
  • 测试
> pavlab.normalize(df = df.example, UMI = count.list)
          a         b         c
1 -14.60964 -15.34661 -15.13571
2 -15.60964 -15.12421 -14.87267
3 -14.60964 -14.76164 -15.13571
4 -14.02468 -15.34661 -15.13571

相关问题