我在R中编写了一个函数,它允许我将度数(弧度)转换为基点(N,W,S,......)。
degree2cardinal <- function(x) {
upper <- seq(from = 11.25, by = 22.5, length.out = 17)
upper <- append(upper, rep(NA, times=5))
card1 <- c('N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N', '', '-', '--', '---', 'NA')
compare <- x<=upper
card1[which(compare)][1]
}
我添加了常见符号,而不是NA
。它虽然有点慢但我相信必须是一种更快的方式。该函数的输入是从0
到360
的任何正双倍。
我将提供一个大小相当的例子。
> set.seed(360)
> deg <- sample(x = seq(from = 0, to = 360, by=0.01), 400000, replace=T)
> system.time(sapply(deg, degree2cardinal))
user system elapsed
14.45 0.00 14.96
答案 0 :(得分:0)
您可以使用findInterval
功能,这将使您的代码速度提高40-50倍:
d2c.2 <- function(x) {
upper <- seq(from = 11.25, by = 22.5, length.out = 17)
card1 <- c('N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N')
ifelse(x>360 | x<0,NA,card1[findInterval(x,upper,rightmost.closed = T)+1])
}
请注意,我的解决方案中没有处理“常用符号”。
library(rbenchmark)
set.seed(360)
deg <- sample(x = seq(from = 0, to = 360, by=0.01), 40000, replace=T)
d2c.sapply <- function(z) sapply(z, degree2cardinal)
benchmark(d2c.sapply(deg),d2c.2(deg))
# test replications elapsed relative user.self sys.self user.child sys.child
# 2 d2c.2(deg) 100 1.507 1.000 1.339 0.168 0 0
# 1 d2c.sapply(deg) 100 66.576 44.178 65.749 0.620 0 0