我是R和这个网站的新手。我的以下目标(当然是不必要的)代码的目的是创建一个R函数,该函数在ggplot2中生成特殊类型的箱形图。首先,我需要通过计算稍后将要绘制的变量来处理其中的潜在输入。
我首先生成一些随机数据,称为datos
:
c1=rnorm(98,47,23)
c2=rnorm(98,56,13)
c3=rnorm(98,52,7)
fila1=as.matrix(t(c(-2,15,30)))
colnames(fila1)=c("c1","c2","c3")
fila2=as.matrix(t(c(-20,5,20)))
colnames(fila2)=c("c1","c2","c3")
datos=rbind(data.frame(c1,c2,c3),fila1,fila2)
rm(c1,c2,c3,fila1,fila2)
然后,我计算变量稍后被绘制,其中包括在每个本列的datos
平均值(puntoMedio
)中,第一和第三四分位数(cuar1
,cuar3
),内四分位范围(iqr
),下限电位submean晶须(limInf
),潜在的超均值晶须(limSup
)和离群值的上限(子均值离群值vAtInf
和超均值离群值vAtSup
合并在中vAt
):
puntoMedio=apply(datos,MARGIN=2,FUN=mean)
cuar1=apply(datos,MARGIN=2,FUN=quantile,probs=.25)
cuar3=apply(datos,MARGIN=2,FUN=quantile,probs=.75)
cuar=rbind(cuar1,cuar3)
iqr=apply(cuar,MARGIN=2,FUN=diff)
cuar=rbind(cuar,iqr,puntoMedio)
limInf=array(dim=ncol(datos))
for(i in 1:ncol(datos)){
limInf0=as.matrix(t(cuar[1,]-1.5*cuar[3,]))
if(length(datos[datos[,i]<limInf0[,i],i])>0){
limInf[i]=limInf0[,i]
}else{limInf[i]=min(datos[,i])}
}
limSup=array(dim=ncol(datos))
for(i in 1:ncol(datos)){
limSup0=as.matrix(t(cuar[2,]+1.5*cuar[3,]))
if(length(datos[datos[,i]>limSup0[,i],i])>0){
limSup[i]=limSup0[,i]
}else{limSup[i]=max(datos[,i])}
}
d=data.frame(t(rbind(cuar,limInf,limSup)))
rm(cuar)
vAtInf=datos
for(i in 1:ncol(vAtInf)){
vAtInf[vAtInf[,i]>limInf0[,i],i]=NA
}
colnames(vAtInf)=c("vAtInfc1","vAtInfc2","vAtInfc3")
vAtSup=datos
for(i in 1:ncol(vAtSup)){
vAtSup[vAtSup[,i]<limSup0[,i],i]=NA
}
colnames(vAtSup)=c("vAtSupc1","vAtSupc2","vAtSupc3")
datos=cbind(datos,vAtInf,vAtSup)
rm(limInf0,limSup0,cuar1,cuar3,i,iqr,limInf,limSup,puntoMedio)
直到这里一切都按预期进行。我有两个数据框d
和datos
,前一个在这里不感兴趣,而后者在此特定情况下包括九列:所有值中的三个,三个对应的子均值离群值,三个对应的超均值离群值(后六个填充与NA)。我现在希望按列提取所有离群值,因此我尝试制定以下循环。尽管它的工作原理既没有给出错误也没有警告,但它也没有给出所需的输出vAt
(再次,来自的按列[列4:9]异常值datos
)。据我所知,这个问题出现在嵌套的for循环中,当您尝试输入i
到vAt
:循环的每次迭代都将擦除最后一次迭代,因此在整个循环完成后,vAt
仅包含NA和最后一列/最后一次迭代中的异常值。
for(i in ((ncol(datos)/3)+1):ncol(datos)){
vAt=matrix(nrow=.25*nrow(datos),ncol=ncol(datos)-(ncol(datos)/3))
colnames(vAt)=c(((ncol(datos)/3)+1):ncol(datos))
if(length(datos[,i][is.na(datos[,i])==F])>0){
for(j in 1:(length(datos[,i][is.na(datos[,i])==F]))){
nom=as.character(i)
vAt[j,nom]=datos[,i][is.na(datos[,i])==F][j]
}
}else{next}
}
我无法找到任何可以回答我问题的线程。谢谢你的帮助。
问题是您要vAt
在这里在循环内部进行初始化。将初始化语句移到for
循环外将解决您面临的问题:
vAt=matrix(nrow=.25*nrow(datos),ncol=ncol(datos)-(ncol(datos)/3))
colnames(vAt)=c(((ncol(datos)/3)+1):ncol(datos))
for(i in ((ncol(datos)/3)+1):ncol(datos)){
if(length(datos[,i][is.na(datos[,i])==F])>0){
for(j in 1:(length(datos[,i][is.na(datos[,i])==F]))){
nom=as.character(i)
vAt[j,nom]=datos[,i][is.na(datos[,i])==F][j]
}
}else{next}
}
但是,您可以对代码进行各种改进:
vectorisation
和*ply
函数代替for
循环。==F
而仅使用!is.na(...)
。sum(is.na(...))
代替length(d[,i][!is.na(...)])
还有更多。这些不会改变代码的正确性,但是会使代码更高效,更惯用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句