gpt4 book ai didi

R:避免使用 for 循环顺序选择一列中的值并使用另一列中的值向量应用函数

转载 作者:行者123 更新时间:2023-12-03 21:59:35 26 4
gpt4 key购买 nike

问题

我正在尝试修改当前采用嵌套 for 循环形式的代码,以便它在不依赖循环的情况下实现相同的结果,如果可能的话,以提高可读性并促进故障排除。我将介绍我实际尝试做的事情的真正简化版本。任何有助于避免循环的建议将不胜感激。

我有一个带有 2 个变量(x,y)的数据框(df)。对于 x1 的值,我想减去 y 的每个值。然后我想对 x2 到 xi 重复这个。

这是帮助说明的图像:

enter image description here

我试过的

一个简单的可重现示例:

数据:

x <- c(221.7, 285.9, 22.3, 67.2, 133.2)
y <- c(121.5, 193.8, 226.2, 313.6, 17.9)
df <- as.data.frame(cbind(x,y))

循环:
outcome <- c()
for (i in seq(1,length(df$x),1)){
eachX <- df[i,1]
outcome[[i]] <- df$y-eachX
}
outcome

我需要帮助的地方

这种方法依赖于 for 循环,我的印象是通常可以避免 for 循环。

提前致谢!

最佳答案

我想你需要 outer :

outer(df$y, df$x, `-`)
# [,1] [,2] [,3] [,4] [,5]
# [1,] -100.2 -164.4 99.2 54.3 -11.7
# [2,] -27.9 -92.1 171.5 126.6 60.6
# [3,] 4.5 -59.7 203.9 159.0 93.0
# [4,] 91.9 27.7 291.3 246.4 180.4
# [5,] -203.8 -268.0 -4.4 -49.3 -115.3

从您的代码:

do.call(cbind, outcome)
# [,1] [,2] [,3] [,4] [,5]
# [1,] -100.2 -164.4 99.2 54.3 -11.7
# [2,] -27.9 -92.1 171.5 126.6 60.6
# [3,] 4.5 -59.7 203.9 159.0 93.0
# [4,] 91.9 27.7 291.3 246.4 180.4
# [5,] -203.8 -268.0 -4.4 -49.3 -115.3

请注意,函数(在本例中为 `-`)被调用一次,长向量覆盖了每个向量的所有对。例如:

minus <- function(...) { `-`(...); }
outer(df$y, df$x, minus)
# [,1] [,2] [,3] [,4] [,5]
# [1,] -100.2 -164.4 99.2 54.3 -11.7
# [2,] -27.9 -92.1 171.5 126.6 60.6
# [3,] 4.5 -59.7 203.9 159.0 93.0
# [4,] 91.9 27.7 291.3 246.4 180.4
# [5,] -203.8 -268.0 -4.4 -49.3 -115.3
### same results

debug(minus)
outer(df$y, df$x, minus)
# debugging in: FUN(X, Y, ...)
# debug at #1: {
# -...
# }
list(...) # <--- view what arguments were passed to our 'minus'
# [[1]]
# [1] 121.5 193.8 226.2 313.6 17.9 121.5 193.8 226.2 313.6 17.9 121.5 193.8 226.2 313.6 17.9
# [16] 121.5 193.8 226.2 313.6 17.9 121.5 193.8 226.2 313.6 17.9
# [[2]]
# [1] 221.7 221.7 221.7 221.7 221.7 285.9 285.9 285.9 285.9 285.9 22.3 22.3 22.3 22.3 22.3
# [16] 67.2 67.2 67.2 67.2 67.2 133.2 133.2 133.2 133.2 133.2

因此,如果您的实际问题具有更复杂的函数(可能更喜欢一次处理一对数据),那么您可能需要考虑如何正确对其进行矢量化,例如使用 mapply .

有人问性能。

microbenchmark::microbenchmark(
r2_vec = outer(y, x, `-`),
r2_df = outer(df$y, df$x, `-`),
akrun1_vec = crossing(y, x) %>% transmute(col = y - x),
akrun2_vec = sapply(y, `-`, x),
akrun2_df = sapply(df$y, `-`, df$x),
hammoire_vec = map(x, function(x0){ y - x0 }),
hammoire_df = map(df$x, function(x){ df$y - x })
)
# Unit: microseconds
# expr min lq mean median uq max neval
# r2_vec 5.1 6.45 9.967 8.50 12.45 44.7 100
# r2_df 16.0 19.30 25.565 21.90 32.40 80.1 100
# akrun1_vec 3433.6 3702.50 3912.103 3827.45 4041.50 5545.7 100
# akrun2_vec 19.5 23.05 30.787 26.85 38.30 59.5 100
# akrun2_df 31.9 36.85 47.008 41.50 56.25 111.3 100
# hammoire_vec 19.8 25.10 28.527 28.35 31.30 45.4 100
# hammoire_df 53.6 59.65 65.561 62.95 71.95 90.2 100

我应该注意到只有 hammoire 和你的 outcome 完全一样:我的是一个矩阵; akrun1 是单列; akrun2 就像我的,但一个是另一个的换位。只有 hammoire 是一个向量列表,不确定这是否是您最终需要的。

关于R:避免使用 for 循环顺序选择一列中的值并使用另一列中的值向量应用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60470054/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com