为什么我的R函数抛出错误

时间:2014-06-16 19:27:38

标签: r ggplot2

我正在尝试将这段代码转换为R函数

separea=quantile(foo6$area,seq(0,1,0.001),na.rm=T)
nb=length(separea)[1]-1
resultats=matrix(NA,nb,8)
for (count in 1:nb){
  print(c("area: ",separea[count] ))
  b=foo6[foo6$area >= separea[max(1,count-20)] & foo6$area <= separea[min(count+20,nb+1)],]
  q01 = quantile( b$nq , 0.01,na.rm=T)  
  q10 = quantile( b$nq , 0.10,na.rm=T)
  q25 = quantile( b$nq , 0.25,na.rm=T)
  q50 = quantile( b$nq , 0.50,na.rm=T)
  q75 = quantile( b$nq , 0.75,na.rm=T)
  q90 = quantile( b$nq , 0.90,na.rm=T)
  q99 = quantile( b$nq , 0.99,na.rm=T)  
  if(dim(b)[1]>100){
    resultats[count,]=cbind(separea[count],q01,q10,q25,q50,q75,q90,q99)
  }
}
resultats=resultats[!is.na(resultats[,1]),]
dim1=dim(resultats)[1]

我写了这个函数:

quantile.prep<-function(dframe,xvar,yvar){
  separea=quantile(dframe$xvar,seq(0,1,0.001),na.rm=T)
  nb=length(separea)[1]-1
  resultats=matrix(NA,nb,8)
  for (count in 1:nb){
    print(c("area: ",separea[count] ))
    b=dframe[dframe$xvar >= separea[max(1,count-20)] & dframe$area <= separea[min(count+20,nb+1)],]
    q01 = quantile( b$yvar , 0.01,na.rm=T)  
    q10 = quantile( b$yvar , 0.10,na.rm=T)
    q25 = quantile( b$yvar , 0.25,na.rm=T)
    q50 = quantile( b$yvar , 0.50,na.rm=T)
    q75 = quantile( b$yvar , 0.75,na.rm=T)
    q90 = quantile( b$yvar , 0.90,na.rm=T)
    q99 = quantile( b$yvar , 0.99,na.rm=T)  
    if(dim(b)[1]>100){
      resultats[count,]=cbind(separea[count],q01,q10,q25,q50,q75,q90,q99)
    }
  }
  resultats=resultats[!is.na(resultats[,1]),]
  dim1=dim(resultats)[1]
}

但我收到此错误: dframe $ xvar中的错误:$运算符对原子矢量无效

当我使用 quantile.prep调用时(dframe ='foo6',xvar ='area',yvar ='nq')

dput(droplevels(head(foo6)))

structure(list(area = c(162.6513, 162.6513, 162.6513, 162.6513, 
162.6513, 162.6513), nq = c(0.140843018162167, 0.152855833307204, 
0.193245919337872, 0.156860105022216, 0.171658019333384, 0.18628194179819
)), .Names = c("area", "nq"), row.names = c(NA, 6L), class = "data.frame")

你能帮忙吗?

建议输出enter image description here

工作解决方案

quantile.prep<-function(dframe,xvar,yvar){
  separea=quantile(dframe[,xvar],seq(0,1,0.001),na.rm=T)
  nb=length(separea)[1]-1
  resultats=matrix(NA,nb,8)
  for (count in 1:nb){
    print(c("area: ",separea[count] ))
    b=dframe[dframe[,xvar]>= separea[max(1,count-20)] & dframe[,'xvar']<= separea[min(count+20,nb+1)],]
    q01 = quantile( b[,yvar] , 0.01,na.rm=T)  
    q10 = quantile( b[,yvar] , 0.10,na.rm=T)
    q25 = quantile( b[,yvar] , 0.25,na.rm=T)
    q50 = quantile( b[,yvar] , 0.50,na.rm=T)
    q75 = quantile( b[,yvar] , 0.75,na.rm=T)
    q90 = quantile( b[,yvar] , 0.90,na.rm=T)
    q99 = quantile( b[,yvar] , 0.99,na.rm=T)  
    if(dim(b)[1]>100){
      resultats[count,]=cbind(separea[count],q01,q10,q25,q50,q75,q90,q99)
    }
  }
  resultats=resultats[!is.na(resultats[,1]),]
  dim1=dim(resultats)[1]
}

1 个答案:

答案 0 :(得分:1)

这样做你想要的吗?

# An example data set
area = seq( log10(10), log10(10000), length.out=5000 )
discharge = seq(1,0.08,length.out=5000) + rnorm(5000, 0, 0.2)
df = data.frame( area=area, nq=discharge )

# Quick peak at the data
plot( df )

# Bin the data into 1,000 bins
# If I read your code right, you are essentially looking at 
# a window of your data that has
# a width of of 40/1000*range(data[,"area"])
# You are looking at that window at 1,000 evenly spaced points
# along the x-axis (here saved as xout)
xout = seq( min(df[,"area"]), max(df[,"area"]), length.out=1000)
window.size = 40/1000*diff(range(df[,"area"]))
results = matrix(NA,nrow=length(xout),ncol=8) # allocate matrix that stores quantiles
for( i in seq_along(xout) ) {

  window = df[,"area"] < (xout[i] + window.size/2) &
           df[,"area"] > (xout[i] - window.size/2)
  values = df[window,"nq"]
  quantiles = quantile(values, probs=c(0.01,0.1,0.25,0.5,0.75,0.9,0.90), na.rm=TRUE )
  results[i,] = c(xout[i],quantiles)
}

# Now plot the results
library(reshape)
library(ggplot2)
colnames(results) = c("area","q01","q10","q25","q50","q75","q90","q99")
results = as.data.frame(results)
melted.results = melt(results, id.vars="area")
ggplot() + 
  geom_point(data=df, aes(x=area,y=nq), alpha=0.15) +
  geom_line(data=melted.results,aes(x=area,y=value,group=variable,color=variable),size=2)

enter image description here