【问题标题】:Assigning values based on the number of character duplicates根据字符重复的数量分配值
【发布时间】:2011-09-27 22:05:16
【问题描述】:

对不起,一个又一个的问题突然爆发。尽我最大的努力搜索,但我有一项艰巨的任务是提出一个非常非常大的程序,而且我对 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(改变强度值并不重要)。

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

提前感谢您的帮助,

【问题讨论】:

  • 只是想感谢您花时间发布一个清晰且可重复的示例。

标签: r conditional duplicate-data


【解决方案1】:

需要注意的是,几乎可以肯定有更有效的方法可以做到这一点(如果您的数据对每个基因有很多重复,则合并操作对包含计数的非常浓缩的 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

【讨论】:

    【解决方案2】:

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

    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
        })
    

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

    【讨论】:

    • 感谢你们的帮助,我最终使用了 plyr 包,但是 gsk3 教会了我一些我打算使用的非常酷的新命令。我有一个关于尼克包裹的快速问题。这可能是不可能的,但对于基因 B,它为每个值分配一个强度值为零。是否可以只为 NA 的值分配零强度值。基因 B 的强度值不是 0、0、0,而是 10、0、0?再次感谢你们两位,非常感谢您的宝贵时间。
    • 没关系,我想通了。我删除了这一行:dfr$IntensityValue
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    相关资源
    最近更新 更多