【问题标题】:Replacement of a negative value in df for the same value divided by two将 df 中的负值替换为相同的值除以 2
【发布时间】:2017-02-04 04:07:10
【问题描述】:

我尝试编写一个函数,将向量中的值替换为相同的值除以二。

# replacement function for a vector
rep <- function(x)
  x.half <- {abs(replace(x, which(x<0),x/2))}

但是,我知道这个函数不能正常工作,因为如果我用负数和正数模拟一个向量,我会得到错误的结果:

a <- c(1,-1,2,-2,3,-3,4,-4,5,-5,11,-11,12,-12,13,-13,21,-21,25,-25)
a.rep <- rep(a)

# data frame to test 
test <- cbind(a,a.rep)

此外,当我将此函数应用于向量 a 时,我会收到如下警告消息:

警告信息: 在替换(x, which(x

显然,我的功能有问题。

【问题讨论】:

  • 那是我函数的一个很短的版本,很好。但是我只需要将负值减半,所有正值都不能更改。
  • a[which(a&lt;1)]=a[which(a&lt;1)]/2 这样就可以了,不需要为此编写函数。
  • 刚刚意识到这是最好和最短的答案:D 谢谢@ChirayuChamoli
  • @mariansess 感谢您的友好评论。

标签: r function


【解决方案1】:

replace 中的第三个参数的长度必须与第二个中子集的值的长度相同。

## determine which values are below zero
a0 <- a < 0
## replace them with their halved values
replace(a, a0, a[a0] / 2)
 [1]   1.0  -0.5   2.0  -1.0   3.0  -1.5   4.0  -2.0   5.0  -2.5  11.0
[12]  -5.5  12.0  -6.0  13.0  -6.5  21.0 -10.5  25.0 -12.5

【讨论】:

    【解决方案2】:

    虽然问题已经得到解答,但我觉得添加算术解决方案是个挑战。

    表达式

    (sign(a) + 3) / 4 * a
    

    会回来

    # [1]   1.0  -0.5   2.0  -1.0   3.0  -1.5   4.0  -2.0   5.0  -2.5  11.0  -5.5  12.0  -6.0  13.0  -6.5
    #[17]  21.0 -10.5  25.0 -12.5
    

    根据要求。

    它是如何工作的

    要求是这样的

    • 负数应乘以1/2
    • 不应更改正数。

    这可以翻译成

    • 如果sign(a) == -1 则将a 乘以1/2
    • 如果sign(a) == +1 则将a 乘以1

    现在,我们需要找到一个满足方程的线性函数y = f(x) = p * x + q

    • f(-1) = -p + q = 1/2
    • f(1) = p + q = 1.

    在求解 pq 后,我们得到 f(x) = 1/4 * x + 3/4。使用 x = sign(a),将 a 的每个元素乘以的因子是:

    1/4 * 符号(a) + 3/4

    【讨论】:

      【解决方案3】:

      你可以使用ifelse():

      half_if_neg <- function(x) {ifelse(x < 0, x / 2, x)}
      #sapply(a, half_if_neg)
      half_if_neg(a)
      

      【讨论】:

      • ifelse 是矢量化的,所以需要sapply()
      【解决方案4】:

      我们也可以做任务

      i1 <- a < 0
      a[i1] <- a[i1]/2
      

      或者使用

      pmax(a, (a*NA^(a >=0))/2, na.rm = TRUE)
      #[1]   1.0  -0.5   2.0  -1.0   3.0  -1.5   4.0  -2.0   5.0  -2.5  11.0 
      #[12] -5.5  12.0  -6.0  13.0  -6.5  21.0 -10.5  25.0 -12.5
      

      【讨论】:

      • @RichScriven 这是一种替代方法。我相信您的replace 方法也很新颖。
      • @RichScriven 我没有找到任何人在答案中使用它。如果您在谈论 cmets,对不起,我没有检查 cmets。无论如何,我还添加了一种非常原始的替代方法
      • @RichScriven 顺便说一句,你认为这不会有任何欺骗的机会,对吧?
      猜你喜欢
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 2019-12-22
      • 2014-07-13
      • 1970-01-01
      • 2020-04-22
      相关资源
      最近更新 更多