R函数用于将度数转换为基数点

时间:2015-02-04 17:43:10

标签: r

我在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。它虽然有点慢但我相信必须是一种更快的方式。该函数的输入是从0360的任何正双倍。

我将提供一个大小相当的例子。

> 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

1 个答案:

答案 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