对于问题后的突发问题,我们深表歉意。尽我所能搜索,但我有一个艰巨的任务,想出一个非常非常大的程序,我仍然是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(改变强度值并不重要)。
我希望这很清楚,我也知道我的其他问题有点容易,所以我希望这个特别的问题不是那么简单,我应该做更多的研究来自己找到答案。 / p>
提前感谢您的帮助,
乔
答案 0 :(得分:2)
如果您不关心data.frame的顺序,ddply
包中的plyr
可以解决问题:
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
})
但是还有很多其他解决方案。
答案 1 :(得分: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