ggplot 在不同的 data.frames 中带有 x 和 y 变量,带有 For-Loop
Posted
技术标签:
【中文标题】ggplot 在不同的 data.frames 中带有 x 和 y 变量,带有 For-Loop【英文标题】:ggplot with x and y variables in different data.frames with a For-Loop 【发布时间】:2021-09-29 21:21:14 【问题描述】:我的 x 和 y 值有两个 data.frames。这样做是因为每一行代表来自同一个体的多个样本,并且每个个体 也 具有唯一的 x 值。我的 y 值表示例:
Group | subgroup | rank | diameter | ID | peak 1 |
peak 2 |
peak 3 |
peak 4 |
peak 5 |
---|---|---|---|---|---|---|---|---|---|
Hym | Polistes | 6 | 4.3 | AD39 | 241.878 | 390.415 | 518.534 | 625.108 | 742.561 |
Dip | Callip | 4 | 3.2 | AD42 | 45.937 | 102.299 | 151.484 | 182.305 | NA |
(但有约 200 行和额外的“峰值”列,最高可达“峰值 16”)
以及我的 x 值表的样本:
ID | disp1 | disp2 | disp3 | disp4 | disp5 |
---|---|---|---|---|---|
AD39 | 0.0591 | 0.118 | 0.177 | 0.236 | 0.295 |
AD42 | 0.102 | 0.203 | 0.305 | 0.406 | 0.508 |
(同样,“disp”列上升到“disp16)
所以,我这里有 2 个样本,基本上都在经历应力-应变曲线。 “峰值”是来自给定位移量的力(g),我的 x 值,表示为被压缩的总直径的比例(即位移/总直径。每个位移步长为 0.254mm,因此 disp1 = 0.254 /总直径,disp2=0.508/总直径等)。
对于我的散点图,y 值是“峰值”列,x 值是我的“分布”值。 这意味着 AD39 第一个点的坐标是 (0.0591,241.878),第二个是 (0.118,390.415),依此类推。从 AD42 可以看出,并非所有 x 值都有对应的 y 值。
我使用 For 循环配对数据
dy<-read_excel(file name for y-value table)
dx<-read_excel(file name for y-value table)
n<- nrow(dx)
disp<- data.frame(NA, dim = c(n,16))
peak<- data.frame(NA, dim = c(n,16))
for (i in 1:n)
for (j in 1:16)
disp[i,j]<- dx[i,j+1]
peak[i,j]<- dy[i,j+6]
names(disp)<- c(1:16)
names(peak)<- c(1:16)
然后我像这样绘制数据:
plot(as.numeric(disp[1,1:16]), as.numeric(peak[1,1:16]), pch = 20, xlab = "displacement", ylab = "peak")
#plot all points
for (i in 2:n)
points(as.numeric(disp[i,1:16]), as.numeric(peak[i,1:16]), pch = 20)
(我承认一个熟人在我花了好几个小时试图让 cbind 工作之后为我做了 for 循环;我真的不太了解 for 循环)
基本上,我的最终目标是能够轻松地将数据分成不同的因素组;前任。我想将我的 37 个等级为“6”的标本与我的 82 个等级为“4”的标本进行比较,方法是将它们绘制在同一组轴上,或者将我的 45 个“Hym”标本与我的 93 个“Dip”标本进行比较。
我想我可以用一堆子集()函数暴力破解代码,但是有太多的因素组,这需要几个小时,并且是世界上最笨拙的代码。
我想在 ggplot 中执行此操作,因为它是更好的绘图包,它还允许您在 ggplot 函数中子集数据。
不幸的是,由于我的 For-Loop,我什至无法在 ggplot 上绘制单个样本。这是我的尝试:
library(ggplot2)
ggplot(data=data.frame(x=(as.numeric(disp[1:16])),y=(as.numeric(peak[1:16]))),aes(x=(as.numeric(disp[1,1:16])), y=(as.numeric(peak[1,1:16]))))+geom_point(size=2,shape=23)
我得到的错误是“data.frame 中的错误(x = (as.numeric(disp[1:16])), y = (as.numeric(peak[1:16]))): 'list' 对象不能被强制输入 'double'"
我认为这个^ 错误是由于我的 data.frame 中的“as.numeric”函数造成的。所以我删除了它,只是为了得到: “错误:美学必须是长度1或与数据相同(167):x和y”
我认为问题是我的 y 值中的 NA 值中包含“NA”。老实说,不知道如何处理。
所以,经过多次波折,我来到了这里。我不确定解决方案是直截了当,还是只能通过改变我处理数据的方式来解决。
【问题讨论】:
我建议将您的数据重新调整为更长的格式,其中每个样本都有一行,然后连接两个表,然后为每个人添加一个汇总值及其排名。将其输入 ggplot 将非常简单,例如。reshaped_data %>% ggplot(aes(disp, peak, group = ID)) + geom_point() + facet_wrap(~rank)
【参考方案1】:
这是我的建议:
首先,将两张表重新整形为长格式:
library(tidyverse)
y_value_long <- y_value_table %>%
pivot_longer(-c(Group:ID), names_prefix = "peak.",
names_transform = list(name = as.integer),
values_to = "peak")
x_value_long <- x_value_table %>%
pivot_longer(-ID, names_prefix = "disp",
names_transform = list(name = as.integer),
values_to = "disp")
加入他们并按等级分面。
left_join(y_value_long, x_value_long, by = c("ID", "name")) %>%
ggplot(aes(disp, peak, group = ID)) +
geom_point() +
geom_path() + # using _path here instead of _line b/c you might have multiple force values yielding the same displacement
facet_wrap(~rank)
【讨论】:
以长格式保存数据总是一个好主意(在 ggplot 的世界中)以上是关于ggplot 在不同的 data.frames 中带有 x 和 y 变量,带有 For-Loop的主要内容,如果未能解决你的问题,请参考以下文章
从零开始学习R语言——数据结构之“数据框(Data Frames)”
如何将列附加到列表中的 data.frames,其中该列应包含计算读取的那些 data.frames 的结构信息?