【问题标题】:R - Basic understanding of using 'apply' instead of nested loopR - 使用“应用”而不是嵌套循环的基本理解
【发布时间】:2014-05-19 23:11:43
【问题描述】:

所以我是 R 新手(我来自 Python 背景),但在理解如何/何时实现 apply 函数(lapply、sapply、rapply 等)而不是嵌套循环时仍然存在一些问题。

举个例子,假设你想执行一些函数 FUN 将列表的每个元素与另一个列表的每个元素进行比较。我会写一些类似的东西:

n = 1
m = 1
sameList = NULL
for(i in 1:length(list1)){
    for(j in 1:length(list2)){
        if(list1[n]==list2[m]){
            sameList<-c(sameList, list1[n]}
    n = n+1
    }
m = m+1
}

换句话说,一些嵌套循环遍历每个列表的每个元素。

我正在学习的是,在 R 中连接列表中间循环是一个非常低效的过程,这就是使用 apply 的原因。

那么如何使用apply(或它的任何版本)来替换上面的示例代码?

【问题讨论】:

  • 针对您的具体示例,如果您可以包含列表示例,可能会有所帮助。另外,也许这篇最近的博客文章很有用:r-bloggers.com/functional-programming-in-r(稍后会查看 for 循环)
  • 您正在调用这两个“列表”,但您正在对它们进行子集化,就好像它们是向量一样。在问 R 问题时请注意这一点。 “列表”是指特定的东西,通常不同于 R 中的“向量”或“原子向量”。
  • ...只是猜测,我认为您根本不需要应用功能。尝试运行outer(1:5,1:5,FUN = "=="),看看这对您是否更有意义。

标签: r performance for-loop nested apply


【解决方案1】:

要使用lapply,您可以运行:

sameList = lapply(list1, function(x) lapply(list2, function(y) if (x==y) x else NULL))

【讨论】:

  • 了解 R 列表和 R 向量之间的区别将在以后对您有所帮助,发布可重复的示例也会对您有所帮助(您没有在问题中定义 list1 或 list2,所以我们不会知道它们是列表还是向量。有很大的不同)。
  • 我建议查看列表与向量的关系,但希望这能让lapply 和嵌套循环在R 中的处理方式更加清晰(outer 是另一个不错的选择) .当您在这里提出问题时,您会收到很多不相关的反馈 - 有些会很好,有些不会很有帮助。
【解决方案2】:

对于这种特殊情况,我会使用

sameList <- intersect(list1, list2)

此外,R 中的术语意味着我们使用vector 表示一种类型的集合; lists 允许包含不同的类型。

避免循环可能是一个美学问题,因为与 apply 相比,循环的性能比以前要好 - 但您注意到的性能下降可能更多是由于不断改变 sameList 的大小(以及随之而来的内存的重新分配)而不是您的代码固有的循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 2011-04-07
    相关资源
    最近更新 更多