【问题标题】:For loop and lapplyFor 循环和 lapply
【发布时间】:2021-11-14 02:20:06
【问题描述】:

首先,我将for loop 用于数字向量,效果很好。

当我使用lapply 函数时,结果不是我想要的。我只想要一个列表中的一个元素。

这是我的例子

# With for loop, the outcome is one vector of numbers
x <- c(0.2,0.5,0.03,0.006,0.08)
p.value <- NULL
for (i in 1:length(x)){
if(x[i] > 0.5 p.value[i] <- (1-x[i])*2
else p.value[i] <- x[i]*2

# with lapply
lapply(x, function(x) {if(x > 0.5) p.value <- (1-x)*2 else p.value <- x*2

lapply 的结果是相同结果的组合。我有点意识到这个问题,但我不知道如何更改我的代码。对此有何建议?

【问题讨论】:

  • 如果你只想要一个向量,你可以包含unlist(),即unlist(lapply(x, function(x) {if(x &gt; 0.5) {p.value &lt;- (1-x)*2} else {p.value &lt;- x*2}}))

标签: r for-loop lapply


【解决方案1】:

这可以通过矢量化方式解决,因此您不需要for 循环或lapply

p.value <- ifelse(x > 0.5, (1 - x), x) * 2

lapply 代码确实为我提供了 for 循环的预期输出,但您可以更改一些内容。

  • 使用sapply,因为输出是一个向量
  • sapply 外部而不是在函数内部分配 p.value
  • 由于您已经有一个名为 x 的向量,请将匿名函数中的变量更改为另一个名称。
p.value <- sapply(x, function(y) if(y > 0.5) (1-y)*2 else y*2)

【讨论】:

  • 哦,谢谢,我知道了。
【解决方案2】:

尝试sapply 而不是lapply。简化列表解决方案

【讨论】:

  • 请注意,unlist(lapply())sapply() 快​​。
【解决方案3】:

您可以使用比ifelse 更快的replace

replace(x, x > .5, 1 - x)*2
# [1] 0.400 1.000 0.060 0.012 0.160

基准测试

x <- sample(x, 1e6, replace=T)
microbenchmark::microbenchmark(ifelse=ifelse(x > 0.5, (1 - x), x) * 2,
                               replace=replace(x, x > .5, 1 - x)*2)
# Unit: milliseconds
#    expr       min       lq     mean   median       uq      max neval cld
#  ifelse 25.049546 31.29303 39.53500 36.23981 42.06574 124.9903   100   b
# replace  8.074329 11.06676 18.68296 14.02976 16.99336 100.2051   100  a 

【讨论】:

    猜你喜欢
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2017-07-12
    • 1970-01-01
    相关资源
    最近更新 更多