R diagrama de dispersión y creé las tres líneas curvas y quería valores que estén cubiertos por las dos líneas exteriores
sugiérame cómo puedo obtener los valores que están entre las dos líneas rojas exteriores
datos utilizados
datos de prueba
código utilizado
library("PerformanceAnalytics")
df=read.table("test",sep='\t', header=TRUE)
pdf('test.pdf',width=6,height=6)
smoothScatter(df$level2,df$level1,main = "data",xlab='level2',ylab='level1',nrpoints=Inf,xlim=c(0,1),ylim=c(0,1),pch=20,cex=0.5)
points(c(0,1),c(1,0),type='l',col='green',lty=2,lwd=2)
points(((1-p)^2)+0.03,(p^2)+0.03,type='l',col='red',lty=2,lwd=2)
points(((1-p)^2)-0.03,(p^2)-0.03,type='l',col='red',lty=2,lwd=2)
p=0:1000/1000
points((1-p)^2,p^2,type='l',col='red',lty=2,lwd=2)
legend(0.30, 1, c("Co", "data_observe"),
col = c("green", "red"), bg = "#FFFFFFAA",
lty = 2, lwd = 4, box.col = "#FFFFFF00")
dev.off()
Gracias
Atrevido de tu parte etiquetar una pregunta de R con Python
Pietro
27/03/2021 a las 10:20
@Pietro Pensé que con algún filtro de datos viendo los valores de la curva se pueden filtrar, con Python
- Sardar afortunado
27/03/2021 a las 10:29
No sé cómo integrar los dos lenguajes, pero si tienes una fórmula de forma cerrada para las líneas rojas, puedes calcular para cada punto de datos los valores ylow y yhigh para las dos líneas usando el valor x del punto de datos y luego verifique si el valor de datos y está entre esos dos.
Pietro
27 de marzo de 2021 a las 10:30
@Pietro Lo intenté pero no pude conseguirlo. ¿Puedes mostrarlo con algún código?
- Sardar afortunado
27/03/2021 a las 10:40
Si no estás intentando identificar automáticamente los puntos, pero puedes hacerlo de forma interactiva, intenta identificar().
- dcarlson
27/03/2021 a las 15:44
------------------------------------
Esto es lo que quise decir:
Calcula la forma cerrada de la frontera, y=f(x), resolviendo para p.
Para cada punto, calcula los valores de los límites para ese valor de x.
Compruebe si el valor de y para ese punto está entre los límites calculados.
Utilice este resultado para crear una variedad de colores, uno por punto.
Todos juntos:
import csv
import matplotlib.pyplot as plt
from pathlib import Path
import numpy as np
def limsup(x):
alpha = 0.03
return (1 - np.sqrt(x - alpha)) ** 2 + alpha
def liminf(x):
alpha = -0.03
return (1 - np.sqrt(x - alpha)) ** 2 + alpha
fig, ax = plt.subplots(1, 1)
data_name = "testdata.tsv"
data_path = Path(data_name)
l1, l2 = [], []
between = []
with data_path.open() as dp_f:
data_tsv = csv.reader(dp_f, delimiter="\t")
next(data_tsv)
for row in data_tsv:
l1val = float(row[1])
l1.append(l1val)
l2val = float(row[2])
l2.append(l2val)
# compute the values of the two boundary for this x value
sup = limsup(l2val)
inf = liminf(l2val)
# if the y value is between the boundary, assing green
if inf <= l1val <= sup:
between.append("green")
else:
between.append("blue")
ax.scatter(l2, l1, c=between, marker=".", label="data")
p = np.linspace(0, 1, 100)
# just to check that the limsup/liminf are correct
# ax.plot((1 - p) ** 2, p ** 2)
# ax.plot((1 - p) ** 2 + 0.03, p ** 2 + 0.03, label="sup")
# ax.plot((1 - p) ** 2 - 0.03, p ** 2 - 0.03, label="inf")
ax.plot(p, np.fromiter((limsup(x) for x in p), dtype=float), label="limsup")
ax.plot(p, np.fromiter((liminf(x) for x in p), dtype=float), label="liminf")
ax.legend()
fig.tight_layout()
plt.show()
Lo que produce esto:
No tengo idea de cómo portar esto a R, pero el razonamiento general debería ser claro.
¡Salud!
1
no es necesario transferir a R cómo obtener los valores de color verde
- Sardar afortunado
27/03/2021 a las 19:11
------------------------------------
Aquí hay un proceso automatizado que compara cada punto con las líneas rojas media e inferior. Habrá una advertencia de que el último valor en yvalu es NaN, pero puedes ignorarlo:
yvalm <- ((2 - sqrt(4 - 4 * (1 - df$level2)))/2)^2 # Middle Red Line
yvalu <- ((2 - sqrt(4 - 4 * (1 - df$level2 + .03)))/2)^2 + .03 # Upper Red Line
# Warning message:
# In sqrt(4 - 4 * (1 - df$level2 + 0.03)) : NaNs produced
yvall <- ((2 - sqrt(4 - 4 * (1 - df$level2 - .03)))/2)^2 - .03 # Lower Red Line
Within <- which(df$level1 > yvall & df$level1 < yvalm)
points(level1~level2, df[Within, ], cex=2, col="red")
El gráfico muestra los puntos identificados.
Ahora enumera los puntos:
df[Within, ]
# data level1 level2
# 149 data2696 0.0813 0.4553
# 660 data3795 0.1393 0.3279
# 672 data3388 0.1789 0.3252
# 742 data536 0.1901 0.3140
# 1430 data1809 0.2750 0.1750
# 1455 data929 0.3220 0.1695
# 1722 data2306 0.4098 0.1230
# 1861 data362 0.4455 0.1000
# 2032 data559 0.5164 0.0574
La solución sugerida por @Pietro también es sencilla en R:
library(sp)
middle <- cbind((1 - p)^2, p^2)
lower <- cbind(rev((1 - p)^2 - 0.03), rev((p^2) - 0.03))
poly <- rbind(middle, lower)
polygon(poly)
inside <- point.in.polygon(df$level2, df$level1, poly[, 1], poly[, 2])
df[inside==1, ]
# data level1 level2
# 149 data2696 0.0813 0.4553
# 660 data3795 0.1393 0.3279
# 672 data3388 0.1789 0.3252
# 742 data536 0.1901 0.3140
# 1430 data1809 0.2750 0.1750
# 1455 data929 0.3220 0.1695
# 1722 data2306 0.4098 0.1230
# 1861 data362 0.4455 0.1000
# 2032 data559 0.5164 0.0574
2
Gracias, pero el problema está en mis puntos de datos reales, hay muchos y me quitará mucho tiempo
- Sardar afortunado
27/03/2021 a las 19:09
He reemplazado la respuesta original con un enfoque diferente.
- dcarlson
28 de marzo de 2021 a las 2:49