【问题标题】:R functions that operate on data frame columns [duplicate]对数据框列进行操作的R函数[重复]
【发布时间】:2013-03-08 19:58:55
【问题描述】:

我有以下功能:

calculateAngle <- function(x, y)
{
    v <- c(x, y)
    a <- c(1, 0)

    theta <- acos( sum(a*v) / ( sqrt(sum(a * a)) * sqrt(sum(v * v)) ) )

    if(v[[2]] < 0)
    {
        return(-1 * theta)
    }
    else
    {
        return(theta)
    }
}

它采用 x 和 y 值并计算该向量与 1、0 向量之间的角度。现在,此函数在这些示例中可以正常工作:

> calculateAngle(0, 1)
[1] 1.570796
> calculateAngle(0, -1)
[1] -1.570796
> calculateAngle(0, -10)
[1] -1.570796
> calculateAngle(rnorm(1), rnorm(1))
[1] -0.2600444

但是当我尝试将数据框的列传递给它时,当我想要的是每行的角度时,它会返回一个值。

df <- data.frame(x=rnorm(10), y=rnorm(10))

df$angle <- calculateAngle(df$x, df$y)

感谢您的帮助。

【问题讨论】:

    标签: r function dataframe


    【解决方案1】:

    (警告:这是一个懒惰的答案,因为我不想花超过 5 秒的时间!)

    calculateAnglev <- Vectorize(calculateAngle,c('x','y'))
    > calculateAnglev(runif(2),runif(2))
    [1] 0.2738694 0.8039875
    

    即在性能方面,这不应被误认为是真正矢量化的替代品。

    【讨论】:

    • FWIW,问题是 sum 函数接受一个向量并返回一个标量。
    • 我想知道这是否会在函数末尾的 OP 的 if 语句中遇到问题? (即如果 x 比 y 长)
    • @RicardoSaporta 我不确定。这只是 mapply 和 OP 函数的包装。因此,如果原始功能有效,这将有效。但是 Hemmo 的回答更好。
    • Joran,如果您也有帮助,您会回答。我会知道查看 Vectorize 以解决未来的问题。谢谢!
    【解决方案2】:

    theta 的代码过于复杂,例如,您的术语 sum(sqrt(a*a)) 始终为 1,而 sum(a*v) 始终为 x。还有sum(v*v) = x^2+y^2,使用这种形式,我们得到了也适用于向量参数的版本:

    calculateAngle <- function(x, y)
    {
       a <- c(1, 0)
       theta <- acos( x / sqrt(x^2+y^2))
       sign(y)*theta
    }
    

    【讨论】:

    • 所以也许我们可以完全删除v...?
    • 完美运行。当代数可以完成时,花了很多时间寻找代码答案。谢谢!
    猜你喜欢
    • 2016-05-17
    • 2018-04-09
    • 2017-01-25
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    相关资源
    最近更新 更多