如何计算 R 中多个向量组合的乘积?
How to calculate the product from combinations of several vectors in R?
虽然我已经尽力了,但我觉得很难给出一个准确的标题。这是我的问题。
a = 1/(1:10)
b = 3/(1:10)
c = 1/(1:5)
d = 1/(1:11)
我想得到一个向量 e
,这样 e
包含根据从 a
、b
、c
和 d
.
例如,假设有两个向量{1, 2}
和{3, 4}
,我想得到一个这样的向量{1 * 3, 1 * 4, 2 * 3, 2 * 4} = {3, 4, 6, 8}
。
提前致谢!
像这样
a <- c(1, 2)
b <- c(3, 4)
现在针对您提出的问题:
apply(expand.grid(a, b), 1, prod)
x <- list(
a=c(1/(1:10)),
b=c(3/(1:10)),
c=c(1/(1:5)),
d=c(1/(1:11))
)
apply(expand.grid(x), 1, prod)
这是一个为两个列表执行此操作的函数。这不是最有效的,但可以完成工作。
my_function <- function(x, y) {
result <- c()
for(i in x) {
for(j in y) {
result <- c(result, i * j)
}
}
return(result)
}
x = c(1, 2)
y = c(3, 4)
my_function(x, y)
# [1] 3 4 6 8
还可以,但是数学上有一个优雅的克罗内克积.
R有一个函数kronecker
,但是它一次取两个向量,所以我们需要Reduce
进行递归应用:
oo <- Reduce(kronecker, list(a, b, c, d))
或者,使用 outer
(kronecker
的主力):
rr <- Reduce(outer, list(a, b, c, d))
这对用户更友好,因为 rr[i, j, u, v]
给你 a[i] * b[j] * c[u] * d[v]
。
备注1
请注意 oo
和 rr
中的元素顺序不同。因为对于两个向量 a
和 b
:
kronecker(a, b) ## a[1] * b, a[2] * b ...
outer(a, b) ## a * b[1], a * b[2] ...
因此,下面使用 kronecker
会产生与 rr
相同的结果。
zz <- Reduce(kronecker, list(d, c, b, a))
dim(zz) <- c(length(a), length(b), length(c), length(d))
备注2
通过将 outer
和 kronecker
中的默认操作 "*"
替换为 "+"
,可以调整该方法来执行 a[i] + b[j] + c[u] + d[v]
。例如:
Reduce(function (x, y) outer(x, y, "+"), list(a, b, c, d))
备注3
可以改进。 apply
的逐行应用是性能杀手。我们可以通过以下操作得到与rr
.
一致的结果
xx <- Reduce("*", expand.grid(a, b, c, d))
dim(xx) <- c(length(a), length(b), length(c), length(d))
虽然我已经尽力了,但我觉得很难给出一个准确的标题。这是我的问题。
a = 1/(1:10)
b = 3/(1:10)
c = 1/(1:5)
d = 1/(1:11)
我想得到一个向量 e
,这样 e
包含根据从 a
、b
、c
和 d
.
例如,假设有两个向量{1, 2}
和{3, 4}
,我想得到一个这样的向量{1 * 3, 1 * 4, 2 * 3, 2 * 4} = {3, 4, 6, 8}
。
提前致谢!
像这样
a <- c(1, 2)
b <- c(3, 4)
现在针对您提出的问题:
apply(expand.grid(a, b), 1, prod)
x <- list(
a=c(1/(1:10)),
b=c(3/(1:10)),
c=c(1/(1:5)),
d=c(1/(1:11))
)
apply(expand.grid(x), 1, prod)
这是一个为两个列表执行此操作的函数。这不是最有效的,但可以完成工作。
my_function <- function(x, y) {
result <- c()
for(i in x) {
for(j in y) {
result <- c(result, i * j)
}
}
return(result)
}
x = c(1, 2)
y = c(3, 4)
my_function(x, y)
# [1] 3 4 6 8
R有一个函数kronecker
,但是它一次取两个向量,所以我们需要Reduce
进行递归应用:
oo <- Reduce(kronecker, list(a, b, c, d))
或者,使用 outer
(kronecker
的主力):
rr <- Reduce(outer, list(a, b, c, d))
这对用户更友好,因为 rr[i, j, u, v]
给你 a[i] * b[j] * c[u] * d[v]
。
备注1
请注意 oo
和 rr
中的元素顺序不同。因为对于两个向量 a
和 b
:
kronecker(a, b) ## a[1] * b, a[2] * b ...
outer(a, b) ## a * b[1], a * b[2] ...
因此,下面使用 kronecker
会产生与 rr
相同的结果。
zz <- Reduce(kronecker, list(d, c, b, a))
dim(zz) <- c(length(a), length(b), length(c), length(d))
备注2
通过将 outer
和 kronecker
中的默认操作 "*"
替换为 "+"
,可以调整该方法来执行 a[i] + b[j] + c[u] + d[v]
。例如:
Reduce(function (x, y) outer(x, y, "+"), list(a, b, c, d))
备注3
apply
的逐行应用是性能杀手。我们可以通过以下操作得到与rr
.
xx <- Reduce("*", expand.grid(a, b, c, d))
dim(xx) <- c(length(a), length(b), length(c), length(d))