if else在ggplot中添加一个额外的图层

joa*_*oal 34 if-statement r ggplot2

说我想在ggplot中绘制两个图层,一个包含点,另一个包含线条,如果满足某个条件.

没有标准的代码可能如下所示:

library("ggplot2")

# Summarise number of movie ratings by year of movie
mry <- do.call(rbind, by(movies, round(movies$rating), function(df) {
  nums <- tapply(df$length, df$year, length)
  data.frame(rating=round(df$rating[1]), year = as.numeric(names(nums)), number=as.vector(nums))
}))

p <- ggplot(mry, aes(x=year, y=number, group=rating))

p + 
geom_point()+
geom_line()
Run Code Online (Sandbox Code Playgroud)

现在绘制点而不仅仅是线条的条件是,一个名为tmp.data的对象不等于表达式"无值".

tmp.data<-c(1,2,3) # in this case the condition is fulfilled

# attempt to plot the two layers including the condition in the plotting function
p+ 
  if(tmp.data[1]!="no value"){ geom_point()+}
  geom_line()
Run Code Online (Sandbox Code Playgroud)

失败....

Error: unexpected '}' in:
"p+ 
if(tmp.data[1]!="no value"){ geom_point()+}"
Run Code Online (Sandbox Code Playgroud)

geom_line()geom_line:
stat_identity:
position_identity :( width = NULL,height = NULL)

Joh*_*aul 36

这是使用ggplot2 2.1.0完成的.我认为你可以做到OP所希望的,只需切换括号,使它们包含整个if语句.

下面是根据如果添加一个水平行的例子SwtichTF.首先,条件是什么TRUE

library(ggplot2)

df<-data.frame(x=1:10,y=11:20)
Switch=T

ggplot(df,aes(x,y))+
{if(Switch)geom_hline(yintercept=15)}+
  geom_point()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

现在,同样的事情,但条件是 FALSE

df<-data.frame(x=1:10,y=11:20)
Switch=F

ggplot(df,aes(x,y))+
{if(Switch)geom_hline(yintercept=15)}+
  geom_point()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 您不能在“{”内使用“+”,但如果有多个步骤,则可以将所有内容放入“列表”中。`{if(Switch)list(geom_hline(yintercept=15), geom_hline(yintercept = 13))}` (10认同)
  • 看来你不能在“{”内部使用“+”,所以如果你想有条件地将多个内容添加到ggplot中,我相信你需要添加另一个“if”语句(在它自己的“{”内部)对于添加到图中的每个对象。 (2认同)

Pau*_*tra 33

你看到的是语法错误.我能想到的最强大的方法是:

tmp.data<-c(1,2,3) 
if(tmp.data[1]!="no value") {
   p = p + geom_point()
}
p + geom_line()
Run Code Online (Sandbox Code Playgroud)

因此,您p按顺序组合对象,仅geom_point()在if语句产生时添加TRUE.


hrb*_*str 5

library(ggplot2)

# Summarise number of movie ratings by year of movie
mry <- do.call(rbind, by(movies, round(movies$rating), function(df) {
  nums <- tapply(df$length, df$year, length)
  data.frame(rating=round(df$rating[1]), year = as.numeric(names(nums)), number=as.vector(nums))
}))

tmp.data<-c(1,2,3) # in this case the condition is fulfilled

p <- ggplot(mry, aes(x=year, y=number, group=rating))

# this won't "loop through" the data points but it's what you asked for
if (tmp.data[1]!="no value") {
  p <- p + geom_point() + geom_line()
} else {
  p <- p + geom_line()
}
p
Run Code Online (Sandbox Code Playgroud)

g1

但也许这更像是你真正想要的?

mry$rating <- factor(mry$rating)
p <- ggplot(mry, aes(x=year, y=number, group=rating))
p <- p + geom_line()
p <- p + geom_point(data=mry[!(mry$rating %in% tmp.data),], 
                    aes(x=year, y=number, group=rating, color=rating), size=2)
p <- p + scale_color_brewer()
p
Run Code Online (Sandbox Code Playgroud)

g2


sah*_*hir 5

按照ggplot2 book,您可以创建一个返回列表的函数。任何 NULL 组件都将被忽略。

library(ggplot2)
library(ggplot2movies)

# Summarise number of movie ratings by year of movie
mry <- do.call(rbind, by(movies, round(movies$rating), function(df) {
    nums <- tapply(df$length, df$year, length)
    data.frame(rating=round(df$rating[1]), year = as.numeric(names(nums)), number=as.vector(nums))
}))

# create function to add points conditionally
# If the list contains any NULL elements, they’re ignored. 
my_plot <- function(point = FALSE){
    list(
        geom_line(),
        if (point) 
            geom_point()
    )

}

p <- ggplot(mry, aes(x=year, y=number, group=rating))
p + my_plot()
Run Code Online (Sandbox Code Playgroud)

p + my_plot(point = TRUE)
Run Code Online (Sandbox Code Playgroud)

reprex 包(v0.3.0)于 2020 年 2 月 25 日创建