我看到有一个内置函数用于......相当抽象......使用从十进制表示形式转换为罗马数字(将罗马数字转换为 R 中的数字),但我无法找到将十进制转换为其他类似系统的内置方法,例如基数 3 或基数 11。我看到二进制和十六进制(基数 16)得到很好的支持,但是是否有用于转换为/从任意位置数字的包系统。
我可以制作这样一个包,但我怀疑它已经存在并且我的 google-fu 只是不够用?
我看到有一个内置函数用于......相当抽象......使用从十进制表示形式转换为罗马数字(将罗马数字转换为 R 中的数字),但我无法找到将十进制转换为其他类似系统的内置方法,例如基数 3 或基数 11。我看到二进制和十六进制(基数 16)得到很好的支持,但是是否有用于转换为/从任意位置数字的包系统。
我可以制作这样一个包,但我怀疑它已经存在并且我的 google-fu 只是不够用?
您可以编写自己的 S3 类:
base <- function(b, base = 10)
{
base <- as.integer(base)
if(base > 36 | base < 2) stop("'base' must be between 2 and 36.")
structure(lapply(b, function(x)
{
n <- ceiling(log(x, base))
vec <- numeric()
val <- x
while(n >= 0)
{
rem <- val %/% base^n
val <- val - rem * base^n
vec <- c(vec, rem)
n <- n - 1
}
while(vec[1] == 0 & length(vec) > 1) vec <- vec[-1]
structure(x, base = base, representation = vec)
}), class = "base")
}
这将需要一个format
andprint
方法:
format.base <- function(b, ...)
{
sapply(b, function(x)
{
glyphs <- c(0:9, LETTERS)
base <- attr(x, "base")
vec <- attr(x, "representation")
paste0(glyphs[vec + 1], collapse = "")
})
}
print.base <- function(b, ...) print(format(b), quote = FALSE)
我们还需要确保数学运算正常工作:
Ops.base <- function(e1, e2) {
base <- attr(e1[[1]], "base")
e1 <- unlist(e1)
e2 <- unlist(e2)
base(NextMethod(.Generic), base)
}
Math.base <- function(e1, e2) {
base <- attr(e1[[1]], "base")
e1 <- unlist(e1)
e2 <- unlist(e2)
base(NextMethod(.Generic), base)
}
如果你想在数据框中使用它,你需要一个as.data.frame
方法:
as.data.frame.base <- function(b, ...)
{
structure(list(b),
class = "data.frame",
row.names = seq_along(b))
}
这一切都允许以下行为:
data.frame(binary = base(1:20, 2), hex = base(1:20, 16), oct = base(1:20, 8))
#> binary hex oct
#> 1 1 1 1
#> 2 10 2 2
#> 3 11 3 3
#> 4 100 4 4
#> 5 101 5 5
#> 6 110 6 6
#> 7 111 7 7
#> 8 1000 8 10
#> 9 1001 9 11
#> 10 1010 A 12
#> 11 1011 B 13
#> 12 1100 C 14
#> 13 1101 D 15
#> 14 1110 E 16
#> 15 1111 F 17
#> 16 10000 10 20
#> 17 10001 11 21
#> 18 10010 12 22
#> 19 10011 13 23
#> 20 10100 14 24
和:
x <- base(67, 11)
y <- base(35, 2)
x + y
#> [1] 93
base(x + y, 10)
#> [1] 102