varias - superponer graficas en r
Ángulo entre dos vectores en R (6)
¿Cuál es la forma más eficiente en el lenguaje de programación R para calcular el ángulo entre dos vectores?
Creo que lo que necesitas es un producto interior. Para dos vectores v,u
(en R^n
o en cualquier otro espacio interno del producto) <v,u>/|v||u|= cos(alpha)
. (si alpha
es el ángulo entre los vectores)
para más detalles ver:
Deberías usar el producto punto. Digamos que tienes V ₁ = ( x ₁, y ₁, z ₁) y V ₂ = ( x ₂, y ₂, z ₂), luego se calcula el producto punto, que indicaré por V ₁ · V ₂ como
V ₁ · V ₂ = x ₁ · x ₂ + y ₁ · y ₂ + z ₁ · z ₂ = | V ₁ | · | V ₂ | · Cos ( θ );
Lo que esto significa es que la suma que se muestra a la izquierda es igual al producto de los valores absolutos de los vectores por el coseno del ángulo entre los vectores. el valor absoluto de los vectores V ₁ y V ₂ se calcula como
| V ₁ | = √ ( x ₁² + y ₁² + z ₁²), y
| V ₂ | = √ ( x ₂² + y ₂² + z ₂²),
Entonces, si reorganizas la primera ecuación de arriba, obtienes
cos ( θ ) = ( x ₁ · x ₂ + y ₁ · y ₂ + z ₁ · z ₂) ÷ (| V ₁ | · | V ₂ |),
y solo necesitas la función arccos (o coseno inverso) aplicada a cos ( θ ) para obtener el ángulo.
Dependiendo de su función arccos, el ángulo puede ser en grados o radianes.
(Para vectores bidimensionales, simplemente olvide las coordenadas z y haga los mismos cálculos).
Buena suerte,
John Doner
Mi respuesta consta de dos partes. La parte 1 es la matemática: para dar claridad a todos los lectores del hilo y hacer comprensible el código R que sigue. La parte 2 es la programación R
Parte 1 - Matemáticas
El producto de puntos de dos vectores xey puede definirse como:
donde || x || es la norma euclidiana (también conocida como la norma L 2 ) del vector x .
Manipulando la definición del producto punto, podemos obtener:
donde theta es el ángulo entre los vectores x y y expresados en radianes. Tenga en cuenta que theta puede tomar un valor que se encuentra en el intervalo cerrado de 0 a pi.
Resolviendo la propia theta, obtenemos:
Parte 2 - Código R
Para traducir las matemáticas en código R, necesitamos saber cómo realizar dos cálculos matriciales (vector); producto puntual y norma euclidiana (que es un tipo específico de norma, conocida como norma L 2 ). También necesitamos saber el equivalente de R de la función de coseno inverso, cos -1 .
A partir de la parte superior. Con referencia a ?"%*%"
, El producto punto (también denominado producto interno) se puede calcular utilizando el operador %*%
. Con referencia a ?norm
, la función norm()
(paquete base) devuelve una norma de un vector. La norma de interés aquí es la norma L 2 o, en el lenguaje de la documentación de ayuda R, la "espectral" o "2" -norma. Esto significa que el argumento de type
de la función norm()
debe ser igual a "2"
. Por último, la función de coseno inverso en R está representada por la función acos()
.
Solución
Equipada con las funciones matemáticas y R relevantes, una función prototipo (es decir, no es un estándar de producción) se puede juntar, usando las funciones del paquete Base, como se muestra a continuación. Si la información anterior tiene sentido, entonces la función de angle()
que sigue debería estar clara sin más comentarios.
angle <- function(x,y){
dot.prod <- x%*%y
norm.x <- norm(x,type="2")
norm.y <- norm(y,type="2")
theta <- acos(dot.prod / (norm.x * norm.y))
as.numeric(theta)
}
Prueba la funcion
Una prueba para verificar que la función funciona. Sean x = (2,1) y y = (1,2). El producto de puntos entre x y y es 4. La norma euclidiana de x es sqrt (5). La norma euclidiana de y también es sqrt (5). cos theta = 4/5. Theta es de aproximadamente 0.643 radianes.
x <- as.matrix(c(2,1))
y <- as.matrix(c(1,2))
angle(t(x),y) # Use of transpose to make vectors (matrices) conformable.
[1] 0.6435011
¡Espero que esto ayude!
Otra solución: la correlación entre los dos vectores es igual al coseno del ángulo entre dos vectores.
por lo que el ángulo puede ser calculado por acos(cor(u,v))
# example u(1,2,0) ; v(0,2,1)
cor(c(1,2),c(2,1))
theta = acos(cor(c(1,2),c(2,1)))
Para los vectores 2D, la forma dada en la respuesta aceptada y en otras no tiene en cuenta la orientación (el signo) del ángulo ( angle(M,N)
es la misma que el angle(N,M)
) y regresa un valor correcto solo para un ángulo entre 0
y pi
.
Utilice la función atan2
para obtener un ángulo orientado y un valor correcto (módulo 2pi
).
angle <- function(M,N){
acos( sum(M*N) / ( sqrt(sum(M*M)) * sqrt(sum(N*N)) ) )
}
angle2 <- function(M,N){
atan2(N[2],N[1]) - atan2(M[2],M[1])
}
Compruebe que angle2
da el valor correcto:
> theta <- seq(-2*pi, 2*pi, length.out=10)
> O <- c(1,0)
> test1 <- sapply(theta, function(theta) angle(M=O, N=c(cos(theta),sin(theta))))
> all.equal(test1 %% (2*pi), theta %% (2*pi))
[1] "Mean relative difference: 1"
> test2 <- sapply(theta, function(theta) angle2(M=O, N=c(cos(theta),sin(theta))))
> all.equal(test2 %% (2*pi), theta %% (2*pi))
[1] TRUE
De acuerdo con la página 5 de este PDF , la sum(a*b)
es el comando R para encontrar el producto punto de los vectores a
y b
, y sqrt(sum(a * a))
es el comando R para encontrar la norma del vector a
, y acos(x)
es el comando R para el arco-coseno. De ello se deduce que el código R para calcular el ángulo entre los dos vectores es
theta <- acos( sum(a*b) / ( sqrt(sum(a * a)) * sqrt(sum(b * b)) ) )