2

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

> 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电话建议吗?

4

3 回答 3

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)
于 2012-05-30T14:25:04.797 回答
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
于 2012-05-30T18:40:43.160 回答
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 运算符更灵活,因为您可以使用列表名称来提供参数名称。

于 2012-12-03T02:15:57.757 回答