首页 文章

将二元函数简洁地应用于(m×2)矩阵的行

提问于
浏览
2

给出以下矩阵,第一列中的权重为ls,第二列中的权重为heshts:

> wgt.hgt.matrix
     [,1] [,2]
[1,]  180   70
[2,]  156   67
[3,]  128   64
[4,]  118   66
[5,]  202   72

我正在寻找一种简洁的方法来应用这个二进制函数

function(lb, inch) { (lb/inch**2)*703 } -> bmi

到矩阵的每一行,得到具有5个结果BMI值的数组,列表或向量 . 我发现的一种方法是使用 apply 函数:

apply(wgt.hgt.matrix, 1, function(row) bmi(row[1], row[2]))

但是Ruby(*)中的splat运算符可以帮助使调用更简洁明了:

apply(wgt.hgt.matrix, 1, function(row) bmi(*row))

是否存在与splat运算符的等价物,即一个语法元素告诉R将所有类似矢量的对象拆分为填充参数列表?对于 apply 电话,还有其他更简单或更简洁的建议吗?

3 回答

  • 0

    使用bmi()函数作为向量化解决方案是优选的,因为它具有所有向量化运算符,如Joshua的答案中所示 . 您也可以这样做:

    colnames(wgt.hgt.matrix) <- c("lb", "inch")
    with( as.data.frame(wgt.hgt.matrix), bmi(lb,inch) )
    # [1] 25.82449 24.43039 21.96875 19.04362 27.39313
    

    不幸的是,矩阵不是使用'with'构建环境的良好基础,因此上面需要强制转换为数据帧 . 你可以得到一个 apply 解决方案(它比矢量化方法的时间效率更低)与bmi()版本一起使用以获取带有命名元素的向量(如上所述):

    bmi <- function(vec) { (vec['lb']/vec['inch']**2)*703 }
     apply(wgt.hgt.matrix, 1, function(row)  bmi(row ) )
    # [1] 25.82449 24.43039 21.96875 19.04362 27.39313
    
  • 1

    也许我错过了什么,但有什么不对:

    wgt.hgt.matrix <-
      structure(c(180L,156L,128L,118L,202L,70L,67L,64L,66L,72L), .Dim=c(5L,2L))
    bmi <- function(lb, inch) (lb/inch**2)*703
    bmi(wgt.hgt.matrix[,1], wgt.hgt.matrix[,2])
    

    更新:

    根据OP的评论,似乎 do.call 会更普遍地运作:

    # put each matrix column in a separate list element
    lc <- lapply(1:ncol(wgt.hgt.matrix), function(i) wgt.hgt.matrix[,i])
    # call 'bmi' with one argument for each column / list element
    do.call(bmi, lc)
    
  • 0

    我们可以使用do.call非常接近您正在寻找的语法:

    ## Setup
    wgt.hgt.matrix=matrix(c(180,70,156,67,128,64,118,66,202,72),ncol=2,byrow=TRUE)
    bmi = function(lb, inch) { (lb/inch**2)*703 }
    ## The action
    apply(wgt.hgt.matrix, 1, function(row) do.call(bmi,as.list(row)))
    

    do.call()实际上比仅仅是一个splat运算符更灵活,因为你可以使用列表名来给出参数名 .

相关问题