R 使用apply()操作多个列

R 使用apply()操作多个列,r,R,我有一个交叉表频率表,其中度量值是CAG,列A01、A02等是频率计数。i、 e.6485个CAG计数为13个,35个CAG计数为14个 我正试图: 设置A01、A02等中Hi的所有值,对于数据操作,我不会使用基数R,尽管这是可能的。我会使用data.table或dplyr包来实现这一点 我必须注意,这不是唯一的方法,必须考虑数据表的开销,然后在前面提到的两个包之间做出决定 由于有n个列,我认为在data.table术语中需要使用.SD和.SDcols。 例如,假设您有A01到A0n列。然后你可

我有一个交叉表频率表,其中度量值是CAG,列A01、A02等是频率计数。i、 e.6485个CAG计数为13个,35个CAG计数为14个

我正试图:


设置A01、A02等中Hi的所有值,对于数据操作,我不会使用基数R,尽管这是可能的。我会使用data.table或dplyr包来实现这一点

我必须注意,这不是唯一的方法,必须考虑数据表的开销,然后在前面提到的两个包之间做出决定

由于有n个列,我认为在data.table术语中需要使用.SD和.SDcols。 例如,假设您有A01到A0n列。然后你可以有:

colsToBeUsed=names(data[,!('CAG')])  

data[ , lapply(.SD, {your formula as a function}), .SDCols=c(colsToBeUsed)]
在任何情况下,在基本R中,lappy比循环更快,这就是我建议使用lappy的原因

在获得关于编码方法的评论后,我提供了两个选项: 首先使用for循环:

library(data.table)
dataDT<- data.frame(CAG = c(13, 14, 15, 17), 
                   A01 = c(6485,35,132, 12), 
                   A02 = c(0,42,56, 4))
thres <- 0.2
dataDT<-setDT(dataDT)
colsToBeUsed<-names(dataDT[,!'CAG'])
sumDataSetdata<-c()  


for(X in colsToBeUsed){
  eval(parse(text=paste0("dataDT[",X,"<thres*max(",X,"),",X,":=0]")))
  eval(parse(text=paste0("dataDT[,MAX",X,":=dataDT[",X,"==max(",X,"),CAG]]")))
  eval(parse(text=paste0("dataDT[,norm",X,":=",X,"/sum(",X,")]")))
  eval(parse(text=paste0("dataDT[,sum",X,":=",X,"/sum(",X,")*(CAG-MAX",X,"),]")))
  eval(parse(text=paste0("sumDataSetdata<-rbind(sumDataSetdata,dataDT[,sum(sum",X,")])")))
  }
第二个是lappy:

library(data.table)
dataDT<- data.frame(CAG = c(13, 14, 15, 17), 
                    A01 = c(6485,35,132, 12), 
                    A02 = c(0,42,56, 4))

thres <- 0.2
dataDT<-setDT(dataDT)

colsToBeUsed<-names(dataDT[,!'CAG'])
sumDataSetdata<-c()
sumDataSet<-unlist(lapply(X=1:length(colsToBeUsed),function(X){s=colsToBeUsed[X]
  eval(parse(text=paste0('dataDT[',s,'<thres*max(',s,'),',s,':=0]')))
  eval(parse(text=paste0('dataDT[,MAX',s,':=dataDT[',s,'==max(',s,'),CAG]]')))
  eval(parse(text=paste0('dataDT[,norm',s,':=',s,'/sum(',s,')]')))
  eval(parse(text=paste0('dataDT[,sum',s,':=',s,'/sum(',s,')*(CAG-MAX',s,'),]')))
  eval(parse(text=paste0('rbind(sumDataSetdata,dataDT[,sum(sum',s,')])')))
  }))

是否有必要在不使用data.table或dplyr包的情况下以这种方式处理数据?我认为使用其中一个包将使您的代码更快、更紧凑。不,当我得到最终结果时,很乐意使用其他包。你有什么建议?谢谢谢谢你们两位。根据实验,我有n个列。你会推荐使用lappy或for循环来将公式应用于多列吗?谢谢,不幸的是,我还没有完全理解它。我已经在上面回复了,如果您能发布一个使用.sds的代码示例,我将不胜感激。抱歉,回答太晚了…这是最简单的:data[,lappy.SD,sum,.SDcols=ccoltobeused],对于自定义函数:data[,lappy.SD,functionX{X/sumX},.SDcols=ccoltobeused]谢谢。我真的很抱歉,但我以前没有使用过.SD,我很难想象如何编写它。你有没有可能用我上面的例子写出代码,然后我可以运行这个答案来查看它的运行情况?
library(data.table)
dataDT<- data.frame(CAG = c(13, 14, 15, 17), 
                   A01 = c(6485,35,132, 12), 
                   A02 = c(0,42,56, 4))
thres <- 0.2
dataDT<-setDT(dataDT)
colsToBeUsed<-names(dataDT[,!'CAG'])
sumDataSetdata<-c()  


for(X in colsToBeUsed){
  eval(parse(text=paste0("dataDT[",X,"<thres*max(",X,"),",X,":=0]")))
  eval(parse(text=paste0("dataDT[,MAX",X,":=dataDT[",X,"==max(",X,"),CAG]]")))
  eval(parse(text=paste0("dataDT[,norm",X,":=",X,"/sum(",X,")]")))
  eval(parse(text=paste0("dataDT[,sum",X,":=",X,"/sum(",X,")*(CAG-MAX",X,"),]")))
  eval(parse(text=paste0("sumDataSetdata<-rbind(sumDataSetdata,dataDT[,sum(sum",X,")])")))
  }
library(data.table)
dataDT<- data.frame(CAG = c(13, 14, 15, 17), 
                    A01 = c(6485,35,132, 12), 
                    A02 = c(0,42,56, 4))

thres <- 0.2
dataDT<-setDT(dataDT)

colsToBeUsed<-names(dataDT[,!'CAG'])
sumDataSetdata<-c()
sumDataSet<-unlist(lapply(X=1:length(colsToBeUsed),function(X){s=colsToBeUsed[X]
  eval(parse(text=paste0('dataDT[',s,'<thres*max(',s,'),',s,':=0]')))
  eval(parse(text=paste0('dataDT[,MAX',s,':=dataDT[',s,'==max(',s,'),CAG]]')))
  eval(parse(text=paste0('dataDT[,norm',s,':=',s,'/sum(',s,')]')))
  eval(parse(text=paste0('dataDT[,sum',s,':=',s,'/sum(',s,')*(CAG-MAX',s,'),]')))
  eval(parse(text=paste0('rbind(sumDataSetdata,dataDT[,sum(sum',s,')])')))
  }))