[英]Concise application of a binary function to rows of a (m x 2) matrix
给定以下矩阵,第一列的权重为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
电话?
也许我缺少了一些东西,但是出了什么问题:
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)
最好使用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
使用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运算符更灵活,因为您可以使用列表名称来指定参数名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.