我只是想计算我的x,y,z数据帧与参考向量之间的相对角度。到目前为止,我使用dplyr
对事物进行分组并应用我的angle
函数来获取相对角度。但是,即使是我在这里提供的虚拟数据,事情也很慢。
set.seed(12345)
x <- replicate(1,c(replicate(1000,rnorm(50,0,0.01))))
y <- replicate(1,c(replicate(1000,rnorm(50,0,0.01))))
z <- replicate(1,c(replicate(1000,rnorm(50,0.9,0.01))))
ref_vector <- data.frame(ref_x=rep(0,100),ref_y=rep(0,100),ref_z=rep(1,100))
set <- rep(seq(1,1000),each=50)
data_rep <- data.frame(x,y,z,ref_vector,set)
&GT;
head(data_rep)
# x y z ref_x ref_y ref_z set
# 1 0.005855288 -0.015472796 0.9059337 0 0 1 1
# 2 0.007094660 -0.013354359 0.9040137 0 0 1 1
# 3 -0.001093033 -0.014661486 0.9047502 0 0 1 1
# 4 -0.004534972 -0.002764655 0.9070553 0 0 1 1
# 5 0.006058875 -0.008339952 0.8926551 0 0 1 1
# 6 -0.018179560 -0.008412400 0.9055541 0 0 1 1
我使用此angle
函数
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)
}
然后将其应用于我们的data_rep
library(dplyr)
system.time(df_angle <- data_rep%>%
rowwise()%>%
do(data.frame(.,angle_rad=angle(unlist(.[1:3]),unlist(.[4:6]))))%>%
group_by(set)%>%
mutate(angle=angle_rad*180/pi, mean_angle=mean(angle)))
# user system elapsed
# 64.22 0.08 64.81
# Warning message:
# Grouping rowwise data frame strips rowwise nature
正如您所看到的,该过程大约需要1分钟,我甚至没有提供所有具有350000行的实际数据集,并且计算相对角度需要10分钟。
我想知道有没有办法加快这个过程。
谢谢!
答案 0 :(得分:21)
为自己发现线性代数:
m1 = as.matrix(data_rep[, 1:3])
m2 = as.matrix(data_rep[, 4:6])
system.time( {
m1 = m1 / sqrt(rowSums(m1 ^ 2))
m2 = m2 / sqrt(rowSums(m2 ^ 2))
RESULT <- acos(rowSums(m1 * m2))
})
# user system elapsed
# 0.004 0.001 0.006
all.equal(df_angle$angle_rad, RESULT)
# TRUE
答案 1 :(得分:7)
只需制作简单的0
语句,而不是mutate
部分。这样可以提高性能,因为您不再需要将每一行转换为do(data.frame())
data.frame