使用apply()来操作多个列

时间:2017-06-26 06:17:59

标签: r

我有一个交叉表频率表,其中度量是CAG,列A01,A02等是频率计数。即64个计数的13个CAG,35个计数的CAG 14。

我正在努力:

  1. 将A01,A02等中的所有值设置为<0.2,即该列中最高值的大小(即排除那些不符合20%阈值的值)。
  2. 通过将该列中的每个值除以该列中所有值的总和来规范化A01,A02等中的每个值。这将为列中的每一行提供0到1之间的值。
  3. 通过CAG中的更改将A01,A02等中的每个值相乘。 CAG中的变化是CAG列中的值减去模态CAG值。
  4. 然后我需要对每列中的所有值求和。
  5. 我在这里有一个刺,但不幸的是我不确定如何进一步发展。非常感谢任何帮助!

    data <- data.frame(CAG = c(13, 14, 15, 17), 
                   A01 = c(6485,35,132, 12), 
                   A02 = c(0,42,56, 4))
    iithreshold <- 0.2
    
    ii <- lapply(data[, 8:ncol(height)], function(x) {
      mod <- data$CAG[which.max(x)]
      x < (iithreshold * max(x)) <- 0
      ii2 <- (x / sum (x)) * (height$CAG - mod)
    })
    
    ii3 <- sum(ii2)
    
    ii3 <- as.data.frame(ii3)
    ii3 <- t(ii3)
    

    好消息!我现在已经开始工作并给出了正确的结果。非常感谢!我必须在某处犯错。我刚从头重新开始。这是工作代码:

    library(data.table) 
    dataDT <- data.frame(height[,7:ncol(height)])
    dataDT <- setDT(dataDT)
    iithreshold <- 0.2
    
    colsToBeUsed<-names(dataDT[,!'CAG'])
    sumDataSetdata<-c()
    iiht<-unlist(lapply(X=1:length(colsToBeUsed),function(X){s=colsToBeUsed[X]
    eval(parse(text=paste0('dataDT[',s,'<iithreshold*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,')])')))
    }))
    

    我一直在努力了解你的每一行功能,但我仍然不确定。对于我的教育,我不认为你能告诉我每个人在做什么? 再次感谢你!

1 个答案:

答案 0 :(得分:1)

嗨我不会使用基数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 lapply比循环更快,这就是为什么我建议使用lapply。

在收到有关编码方式的评论后,我提供了两个选项: 首先使用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,")])")))
  }

第二次是lapply:

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,')])')))
  }))