Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R的ggplot2中使用stat_函数和facet_包装在一起_R_Graph_Ggplot2 - Fatal编程技术网

在R的ggplot2中使用stat_函数和facet_包装在一起

在R的ggplot2中使用stat_函数和facet_包装在一起,r,graph,ggplot2,R,Graph,Ggplot2,我试图用ggplot2绘制晶格类型数据,然后在样本数据上叠加正态分布,以说明基础数据偏离正态的程度。我想把正常距离放在上面,使其与面板的平均值和标准偏差相同 下面是一个例子: library(ggplot2) #make some example data dd<-data.frame(matrix(rnorm(144, mean=2, sd=2),72,2),c(rep("A",24),rep("B",24),rep("C",24))) colnames(dd) <- c("x_

我试图用ggplot2绘制晶格类型数据,然后在样本数据上叠加正态分布,以说明基础数据偏离正态的程度。我想把正常距离放在上面,使其与面板的平均值和标准偏差相同

下面是一个例子:

library(ggplot2)

#make some example data
dd<-data.frame(matrix(rnorm(144, mean=2, sd=2),72,2),c(rep("A",24),rep("B",24),rep("C",24)))
colnames(dd) <- c("x_value", "Predicted_value",  "State_CD")

#This works
pg <- ggplot(dd) + geom_density(aes(x=Predicted_value)) +  facet_wrap(~State_CD)
print(pg)
库(ggplot2)
#制作一些示例数据

我认为你需要提供更多的信息。这似乎有效:

 pg <- ggplot(dd, aes(Predicted_value)) ## need aesthetics in the ggplot
 pg <- pg + geom_density() 
 ## gotta provide the arguments of the dnorm
 pg <- pg + stat_function(fun=dnorm, colour='red',            
            args=list(mean=mean(dd$Predicted_value), sd=sd(dd$Predicted_value)))
 ## wrap it!
 pg <- pg + facet_wrap(~State_CD)
 pg

pg我想你最好的办法是用geom_线手工画线

dd<-data.frame(matrix(rnorm(144, mean=2, sd=2),72,2),c(rep("A",24),rep("B",24),rep("C",24)))
colnames(dd) <- c("x_value", "Predicted_value",  "State_CD")
dd$Predicted_value<-dd$Predicted_value*as.numeric(dd$State_CD) #make different by state

##Calculate means and standard deviations by level
means<-as.numeric(by(dd[,2],dd$State_CD,mean))
sds<-as.numeric(by(dd[,2],dd$State_CD,sd))

##Create evenly spaced evaluation points +/- 3 standard deviations away from the mean
dd$vals<-0
for(i in 1:length(levels(dd$State_CD))){
    dd$vals[dd$State_CD==levels(dd$State_CD)[i]]<-seq(from=means[i]-3*sds[i], 
                            to=means[i]+3*sds[i],
                            length.out=sum(dd$State_CD==levels(dd$State_CD)[i]))
}
##Create normal density points
dd$norm<-with(dd,dnorm(vals,means[as.numeric(State_CD)],
                        sds[as.numeric(State_CD)]))


pg <- ggplot(dd, aes(Predicted_value)) 
pg <- pg + geom_density() 
pg <- pg + geom_line(aes(x=vals,y=norm),colour="red") #Add in normal distribution
pg <- pg + facet_wrap(~State_CD,scales="free")
pg

dd
stat\u功能
设计用于在每个面板中覆盖相同的功能。(没有明显的方法将函数的参数与不同的面板相匹配)

正如Ian所建议的,最好的方法是自己生成法线曲线,并将其作为一个单独的数据集进行绘制(这是您之前出错的地方-对于本例来说,合并没有意义,如果您仔细观察,您会发现这就是为什么会得到奇怪的锯齿图案)

下面是我如何着手解决这个问题:

dd <- data.frame(
  predicted = rnorm(72, mean = 2, sd = 2),
  state = rep(c("A", "B", "C"), each = 24)
) 

grid <- with(dd, seq(min(predicted), max(predicted), length = 100))
normaldens <- ddply(dd, "state", function(df) {
  data.frame( 
    predicted = grid,
    density = dnorm(grid, mean(df$predicted), sd(df$predicted))
  )
})

ggplot(dd, aes(predicted))  + 
  geom_density() + 
  geom_line(aes(y = density), data = normaldens, colour = "red") +
  facet_wrap(~ state) 

<代码> DD < P>如果你不想用手工生成正常的分布线图,仍然使用StaskFor函数,并列显示图形,那么你可以考虑使用“RoopBooR”上的“多图”函数来代替FACETHULLATH。您可以将multiplot代码复制到项目中

复制代码后,请执行以下操作:

# Some fake data (copied from hadley's answer)
dd <- data.frame(
  predicted = rnorm(72, mean = 2, sd = 2),
  state = rep(c("A", "B", "C"), each = 24)
) 

# Split the data by state, apply a function on each member that converts it into a 
# plot object, and return the result as a vector.
plots <- lapply(split(dd,dd$state),FUN=function(state_slice){ 
  # The code here is the plot code generation. You can do anything you would 
  # normally do for a single plot, such as calling stat_function, and you do this 
  # one slice at a time.
  ggplot(state_slice, aes(predicted)) + 
    geom_density() + 
    stat_function(fun=dnorm, 
                  args=list(mean=mean(state_slice$predicted), 
                            sd=sd(state_slice$predicted)),
                  color="red")
})

# Finally, present the plots on 3 columns.
multiplot(plotlist = plots, cols=3)
#一些虚假数据(摘自哈德利的答案)

dd如果你愿意使用GG公式,那么这是非常容易的。(也可以将ggformula混搭在一起,并仅用于分发覆盖,但我将说明完整的ggformula方法。)

库(ggformula)
theme_set(theme_bw())
gf_dens(~萼片长度|种,数据=鸢尾)%>%
gf_FitDisr(color=“red”)%%>%
gf_fitdress(dist=“gamma”,color=“blue”)


由(v0.2.1)创建于2019-01-15,最初作为答案发布,我也被鼓励在这里分享我的解决方案

我也对将理论密度叠加在经验数据上感到沮丧,所以我写了一个函数来自动化这个过程。自2009年首次提出这个问题以来,ggplot2极大地扩展了可扩展性,因此我将其放在github上的扩展包中

库(ggplot2)
图书馆(ggh4x)
种子集(0)
#制作示例数据

dd在将来,您是否可以使用大小写混合或下划线的变量名,但不能同时使用两者。我快死了!好的,好的,这是一个很好的观点我把“答案”移到了问题区。我应该先把它放在那里。我向那些发表评论的人道歉,因为他们没有转移。我会更仔细地考虑我将来怎么做。在你解释之后,这完全是有道理的。对我来说,stat_函数是为单曲线设计的,这是不直观的。我只是认为我做错了。感谢您花时间给出一个示例,它非常有用。
stat\u function
仍然不能为每个面板提供不同的曲线吗?似乎人们只想传递一个命名的函数列表,并将这些名称与给定给
facet\u wrap
的分类变量相匹配,或者将函数作为原始数据表中的参数提供?@cboettig no,这是不可能的。命名列表不适用于多个faceting变量。@hadley我不理解这个问题。为什么不能
stat_function
仅参考在特定面板中绘制的数据框部分来评估其参数?可以通过使用库(plyr)和ddply(dd,((State_CD),summary,…)获得面板特定的平均值和标准差,但。。。OP在顶部声明
“我希望正常距离在顶部具有与面板相同的平均值和标准偏差。”
答案很好,但代码必须符合以下问题:库(ggformula);主题集(theme_bw());dd
dd <- data.frame(
  predicted = rnorm(72, mean = 2, sd = 2),
  state = rep(c("A", "B", "C"), each = 24)
) 

grid <- with(dd, seq(min(predicted), max(predicted), length = 100))
normaldens <- ddply(dd, "state", function(df) {
  data.frame( 
    predicted = grid,
    density = dnorm(grid, mean(df$predicted), sd(df$predicted))
  )
})

ggplot(dd, aes(predicted))  + 
  geom_density() + 
  geom_line(aes(y = density), data = normaldens, colour = "red") +
  facet_wrap(~ state) 
# Some fake data (copied from hadley's answer)
dd <- data.frame(
  predicted = rnorm(72, mean = 2, sd = 2),
  state = rep(c("A", "B", "C"), each = 24)
) 

# Split the data by state, apply a function on each member that converts it into a 
# plot object, and return the result as a vector.
plots <- lapply(split(dd,dd$state),FUN=function(state_slice){ 
  # The code here is the plot code generation. You can do anything you would 
  # normally do for a single plot, such as calling stat_function, and you do this 
  # one slice at a time.
  ggplot(state_slice, aes(predicted)) + 
    geom_density() + 
    stat_function(fun=dnorm, 
                  args=list(mean=mean(state_slice$predicted), 
                            sd=sd(state_slice$predicted)),
                  color="red")
})

# Finally, present the plots on 3 columns.
multiplot(plotlist = plots, cols=3)