2

对不起,一个又一个问题的爆发。尽我最大的努力搜索,但我有一项艰巨的任务是提出一个非常非常大的程序,而且我对 R 还是很陌生,所以我感谢到目前为止我得到的所有快速帮助。

演示问题的假例子

Gene <- c("A","B","C","A","B","C","A","B","C")
> IntensityValue <- c(1,10,20,3,NA,23,NA,NA,22)
> ProceedTest <- c(2,2,2,2,-1,2,-1,-1,2)
> ExampleData <- list(Gene=Gene, IntensityValue=IntensityValue, ProceedTest=ProceedTest)
> ExampleData <- as.data.frame(ExampleData)
> ExampleData
Gene IntensityValue ProceedTest
 A              1           2
 B             10           2
 C             20           2
 A              3           2
 B             NA          -1
 C             23           2
 A             NA          -1
 B             NA          -1
 C             22           2

ProceedTest 是一个分数,指示测试是否应该继续。2 分表示将考虑数据,-1 分表示测试不考虑数据。

你会注意到基因 B 的 NA 出现了两次,而 A 的 NA 只出现了一次。我希望 R 能够识别出基因 B,NA 出现两次。这样任何时候 NA 对于给定基因 (B) 出现两次,零值替换 NA,随后的 -1 变成 2。我希望 R 忽略 A 的 NA 并继续离开 Proceed 测试值原样。

更改后的数据应如下所示:

Gene IntensityValue ProceedTest
  A              1           2
  B             10           2
  C             20           2
  A              3           2
  B              0           2
  C             23           2
  A             NA          -1
  B              0           2
  C             22           2

这可能是不可能的,但如果是的话,我想说如果基因没有 NA,那么 ProceedTest 值将变为 -1。

Final Dataset
 Gene IntensityValue ProceedTest
  A              1           2
  B             10           2
  C             20          -1
  A              3           2
  B              0           2
  C             23          -1
  A             NA          -1
  B              0           2
  C             22          -1

总之。基因 A 只有一个 NA,所以没有任何变化。基因 B 有两个 NA 值,因此它得到全 2,并且 NA 在强度值列中变为零。基因 C 变为 -1,因为它不包含任何 NA(改变强度值并不重要)。

我希望这很清楚,我也知道我的其他问题更容易一些,所以我希望这个特定的问题不是那么简单,我应该做更多的研究来自己找到答案。

我在这里先向您的帮助表示感谢,

4

2 回答 2

2

如果您不关心 data.frame 的顺序,ddplyplyr包中可以解决问题:

ddply(ExampleData, "Gene", function(dfr){
        #here, dfr is the part of your original data.frame
        #only for the 'current value' of Gene
        numNA<-sum(is.na(dfr$IntensityValue))
        if(numNA>1)
        {
            dfr$IntensityValue<-0
            dfr$ProceedTest<-2
        }
        else if(numNA==0)
        {
            dfr$ProceedTest<- -1
        }
        dfr
    })

不过还有很多其他的解决方案。

于 2011-07-04T06:53:01.693 回答
0

需要注意的是,几乎可以肯定有更有效的方法可以做到这一点(如果您的数据对每个基因有很多重复,则合并操作对包含计数的非常浓缩的 data.frame 的重复将占用大量内存):

Gene <- c("A","B","C","A","B","C","A","B","C")
IntensityValue <- c(1,10,20,3,NA,23,NA,NA,22)
ProceedTest <- c(2,2,2,2,-1,2,-1,-1,2)
ExampleData <- list(Gene=Gene, IntensityValue=IntensityValue, ProceedTest=ProceedTest)
ExampleData <- as.data.frame(ExampleData)
ExampleData

num.na <- function(x) {
  sum(is.na(x))
}
ED.numna <- by(data=ExampleData,Gene,num.na)
# res.name is what you want the result column to be named
  #ideally would pull this from the call via something like as.character(attr(x,"call"))
as.data.frame.by <- function(x,res.name=NA) {
  stopifnot(length(dimnames(x))==1) # Only 1d case handled for now
  df <- data.frame(by = names(x), res = as.numeric(x) )
  names(df)[names(df)=="by"] <- names(dimnames(x))
  if(!is.na(res.name)) {
    names(df)[names(df)=="res"] <- res.name
  }
  df
}
ExampleData <- merge(ExampleData,as.data.frame(ED.numna,"count"))
ExampleData$IntensityValue[ExampleData$count > 1] <- 0
于 2011-07-04T07:12:08.390 回答