如何在R中的条件下使用lapply每次仅适合一个元素

时间:2018-07-02 19:30:47

标签: r

假设我有两个向量。进一步假设我希望我的函数对每个向量仅取一个值,然后将输出返回给我。然后,我想要另一个函数来检查每次运行的值。如果上一次运行的输出小于新运行的输出。然后,我希望函数停止并返回所有先前的值。我的原始功能非常复杂(估算模型)。因此,我尝试提供一个例子来解释我的想法。

假设我有以下两个向量:

set.seed(123)
x <- rnorm(1:20)
y <- rnorm(1:20)

然后,我想编写一个仅对每个向量取一个值并将它们相乘的函数。然后,将输出返回给我。然后,我希望该函数检查以前的乘法是否小于新的乘法。如果是,则停止并返回我之前所有的乘法。

我尝试了此操作:但是,此函数一次获取所有值,并向我返回一个乘法列表。我当时在考虑使用lapply来一次适合一个元素,但是我不知道如何使用这些条件。

myfun <- function(x, y, n){
    multi <- list()
    for ( i in 1:n){
        multi[[i]] <- x[[i]]*y[[i]]
    }
    return(multi)
}
myfun(x,y,10)

这是另一种尝试

 x <- rnorm(1:20)
y <- rnorm(1:20)
myfun <- function(x, y){
            multi <- x*y

    return(multi)
}

这是第一个功能。我想逐个运行它。每次,我希望它只返回一个乘法结果。然后,另一个函数(包装函数)检查结果。如果第一个函数(乘法函数)的第二个输出大于第一个函数的第二个输出,然后停止,否则继续进行。

1 个答案:

答案 0 :(得分:0)

  

我想编写一个仅对每个向量取一个值并将它们相乘的函数。然后,将输出返回给我。然后,我希望该函数检查以前的乘法是否小于新的乘法。

     

我想在一个单独的函数中进行乘法运算。然后,我想检查其输出。所以,我应该有一个整经功能。

您可以应用具有停止条件的for循环,类似于您已经拥有的条件:

# example input
set.seed(123)
x <- rnorm(1:20)
y <- rnorm(1:20)

# example function
f = function(xi, yi) xi*yi

# wrapper
stopifnot(length(x) == length(y))
res = vector(length(x), mode="list")

for (i in seq_along(x)){
  res[[i]] = f(x[[i]], y[[i]])
  if (i > 1L && res[[i]] > res[[i-1L]]) break
}

res[seq_len(i)]

评论:

  • 最好预先定义res可能需要的最大长度(此处为length(x)),而不是在循环中进行扩展。
  • 对于此功能(乘法),没有充分的理由按元素进行。 R的乘法函数是矢量化且快速的。
  • 此函数不需要使用列表类输出,因为它返回的是double。 res = double(length(x))也应该起作用。
  • 除非涉及列表,否则您无需为xyres使用列表样式访问器; res[i] = f(x[i], y[i])应该可以工作,等等。