【问题标题】:How do you isolate the digits following a decimal in R?你如何隔离R中小数点后的数字?
【发布时间】:2016-09-30 19:57:46
【问题描述】:

例如:我有数字 123.456,想返回 456。

函数trunc() 基本上隔离(truncates)小数点之前的数字。

有没有一个函数可以只隔离小数点后的数字?

两个后续问题:

  1. 有没有办法在不写出正则表达式的情况下做到这一点?

  2. 如果我想保留标志怎么办?例如,如果我想(反向)将 -123.456 截断为 -456。

【问题讨论】:

  • sign(x) * (abs(x) %% 1)
  • @Gregor 不会是x-trunc(x)
  • 糟糕,错过了需要一个整数。似乎浮点算术问题等着把你搞砸。很高兴许多答案都在处理这个问题,但将其保留为小数似乎更安全。
  • 出于好奇:这有什么用例?
  • @Roland,其实我只需要它来测试是否存在非整数整数。我对如何进一步扩展这个概念很感兴趣,主要是出于好奇。但是,后来我想我无法按照问题的要求提出时尚的方法,所以我问了。

标签: r decimal digit isolation truncated


【解决方案1】:

使用带 1 的模运算符 (%%) 作为除数我猜。它确实成功地隔离了小数点后的数字,但留下了小数点:

123.456 %% 1
[1] 0.456

但是它只适用于正数,因为符号没有保留,也没有报告正确的数字(模运算符功能的 b/c):

-123.456 %% 1
[1] 0.544  #not what is wanted

包含abs() 修复了该问题,但无助于报告符号。可以通过添加来包含符号:

sign(x) * (abs(x) %% 1)

如果我们真的想报告小数点后的数字(即不包括 0 和小数),我们可以执行以下操作(分 2 个步骤呈现为清楚起见):

x <- -123.456
y <- sign(x) * (abs(x) %% 1)
as.numeric(gsub("0.","",y))
[1] -456  #as desired from part 2 in the OP

【讨论】:

  • 我们可以很容易地把它变成一个函数,允许你选择是否在输出中包含符号。我将调用十进制隔离器的函数“decIso”:decIso &lt;- function(x, sign = TRUE) { y &lt;- (abs(x) %% 1) ; z &lt;- ifelse(sign == T, sign(x) * y, y) ; as.numeric(gsub("0.","",z)) }
【解决方案2】:

我不喜欢对这类操作进行文本处理。

棘手的部分是将小数转换为整数。这里我使用了一个循环。不太可能需要多次迭代。因此,性能可能不是问题。

fun <- function(x) {
  y <- abs(x) - floor(abs(x))

  n <- 0
  while (abs(y - round(y, n)) > .Machine$double.eps^0.5) {
    n <- n + 1
  }

  sign(x) * y * 10^n
}

fun(123.456)
#[1] 456
fun(-123.456)
#[1] -456

【讨论】:

    【解决方案3】:

    这是另一种方式

    > x <- c(123.456, -123.456)
    > sign(x) * as.integer(sapply(strsplit(as.character(x), "\\."), "[", 2))
    [1]  456 -456
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 2011-04-22
      相关资源
      最近更新 更多