子集和ggplot2

73

我有一个问题,需要用ggplot2绘制数据帧的子集。我的数据框架如下:

df = data.frame(ID = c('P1', 'P1', 'P2', 'P2', 'P3', 'P3'),
                Value1 = c(100, 120, 300, 400, 130, 140),
                Value2 = c(12, 13, 11, 16, 15, 12))
我现在该如何绘制仅限于ID为'P1'和'P3'的Value1Value2的图形呢? 例如,我尝试过:
ggplot(subset(df,ID=="P1 & P3") +
  geom_line(aes(Value1, Value2, group=ID, colour=ID)))

但我总是收到错误提示。


((ID =="P1") | (ID =="P3")) 可能会起作用。 - Andy Clifton
1
或者 ID %in% c("P1", "P3") - Hong Ooi
@Hong 和 @LostBrit,我收到了两个命令的错误提示:Error in as.vector(x, mode) : cannot coerce type 'environment' to vector of type 'any'。 - matteo
是的,它会产生一个错误。您能否谈谈您试图绘制什么? - Metrics
数据会很有帮助。 - Andy Clifton
10个回答

81

以下有两种子集选项:

使用 R 基础语言中的 subset 函数:

library(ggplot2)
ggplot(subset(dat,ID %in% c("P1" , "P3"))) + 
         geom_line(aes(Value1, Value2, group=ID, colour=ID))

使用subset作为geom_line的参数(注意我正在使用plyr包来使用特殊的.函数)。

library(plyr)
ggplot(data=dat)+ 
  geom_line(aes(Value1, Value2, group=ID, colour=ID),
                ,subset = .(ID %in% c("P1" , "P3")))

你也可以使用补集子集:

subset(dat,ID != "P2")

5
值得一提的是,在"subset"参数被弃用后,可以使用以下语句获取相似的结果:geom_line(data=dat[dat$ID %in% c("P1", "P3"),], ...)。这个讨论中提到了这种方法。实际上,这种方法与下面这个答案的基本原理相同:https://dev59.com/02Ml5IYBdhLWcg3wwZAq#18165706。唯一的区别在于在geom调用中使用了子集数据。 - Konrad
@agstudy @konrad-rudolph 定义 data=function(x) {...} 可以替代 subset - Dave
@agstudy 我的数据框包含3列(年份,降雨量,温度)。因此,当我尝试仅为所选年份绘制图表时,我使用了ggplot(subset(data=aggdata, Year %in% c("1901" , "1910")), aes(x=Year, y=tem, color=factor(Year))),但它显示错误Error in Year %in% c("1901", "1910") : object 'Year' not found。你能告诉我该怎么做吗? - mostafiz67
在 ggplot 中,是否可以对多个列进行子集操作?比如说我想要对 Year == 2022 & Age == 12 进行子集操作,那么我需要对两列进行子集操作。 - FishyFishies

29

我发现另一种解决方案特别有用,尤其是当我想绘制同一对象的多个子集时:

myplot<-ggplot(df)+geom_line(aes(Value1, Value2, group=ID, colour=ID))
myplot %+% subset(df, ID %in% c("P1","P3"))
myplot %+% subset(df, ID %in% c("P2"))

@Nick,是的,你的代码很好用(创建了图表),但在我的情况下没有显示线条!你能告诉我该怎么做吗?[https://i.postimg.cc/85VgpMKz/Screenshot-from-2020-09-29-15-21-54.png] - mostafiz67
1
您已将年份指定为分组变量和颜色。线条在同一组的数据点之间绘制。以这种方式设置图表意味着每个组只有一个观察结果。因此,解决方案是删除“group=Year”。 - Nick Isaac
有没有办法确保颜色不变?例如,如果有四条线,红绿蓝紫,如果你只选择第一条和第四条线,能否保持红色和紫色不变,而不是变成红色和绿色。 - Aaron Walton

15

@agstudy的回答对于我使用最新版本的ggplot2无效,但是这个方法有效,使用maggritr管道:

@agstudy的答案不能适用于我所使用的最新版本的ggplot2,但是以下方法可以,使用maggritr管道:

(两种翻译方式均可)
ggplot(data=dat)+ 
  geom_line(aes(Value1, Value2, group=ID, colour=ID),
                data = . %>% filter(ID %in% c("P1" , "P3")))

这能够起作用是因为如果 geom_line 发现 data 是一个函数,它将使用继承版本的 data 调用该函数,并将该函数的输出用作 data


这还管用吗?不确定他们是否将 . 改成了 .x。虽然在新闻中没有找到任何信息。请参见我的回答。顺便说一下,他们最近改了很多东西。 - andschar
1
@andschar 绝对还可以用。.x都没问题。 - Maurits Evers

14

@agstudy答案中的选项2现已被弃用,使用函数定义数据非常方便。

library(plyr)
ggplot(data=dat) + 
  geom_line(aes(Value1, Value2, group=ID, colour=ID),
            data=function(x){x$ID %in% c("P1", "P3"))

如果您想在同一图中重复使用数据集(例如,您不想在data.frame中指定新列,或者您希望明确地在另一个层上绘制一个数据集),则使用此方法非常方便。

library(plyr)
ggplot(data=dat, aes(Value1, Value2, group=ID, colour=ID)) + 
  geom_line(data=function(x){x[!x$ID %in% c("P1", "P3"), ]}, alpha=0.5) +
  geom_line(data=function(x){x[x$ID %in% c("P1", "P3"), ]})

8

您是否正在寻找以下情节:

library(ggplot2) 
l<-df[df$ID %in% c("P1","P3"),]
myplot<-ggplot(l)+geom_line(aes(Value1, Value2, group=ID, colour=ID))

enter image description here


4

您的表述基本正确。您想要:

subset(dat, ID=="P1" | ID=="P3") 

其中|(“管道”)表示“或”。您的解决方案ID=="P1 & P3"是在寻找ID确切为"P1 & P3"的情况。


2
你可以使用~subset(., ...) - 这是执行Dave上面建议的方法的一种方式,它也
  • 适用于当前{ggplot2}(3.4.2)
  • 不需要{magrittr}管道-对于那些切换到R管道的人
  • 引用作为数据参数输入到ggplot()函数中的数据,例如当数据被连通时
  • 比定义一个函数更简洁/更容易理解
ggplot(mtcars, aes(hp, disp)) +
  geom_point() +
  geom_point(data = ~subset(., cyl == 4), color = "red")

例如,当数据被管道传输时,也可以这样工作:

mtcars |> 
  filter(gear > 3) |> 
  ggplot(aes(hp, disp)) +
  geom_point() +
  geom_point(data = ~subset(., cyl == 4), color = "red")


2
尝试使用筛选器来子集化仅包含P1和P3行的数据。
df2 <- filter(df, ID == "P1" | ID == "P3")

您可以绘制Value1与Value2的图形。


0

在 ggplot 中使用 subset

ggplot(data = subset(df, ID == "P1" | ID == "P2") +
   aes(Value1, Value2, group=ID, colour=ID) +
   geom_line()

0

与 @nicolaskruchten 的回答类似,你可以做以下操作:

require(ggplot2)

df = data.frame(ID = c('P1', 'P1', 'P2', 'P2', 'P3', 'P3'),
                Value1 = c(100, 120, 300, 400, 130, 140),
                Value2 = c(12, 13, 11, 16, 15, 12))

ggplot(df) + 
  geom_line(data = ~.x[.x$ID %in% c("P1" , "P3"), ],
            aes(Value1, Value2, group = ID, colour = ID))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接