为什么`lapply`会自动返回赋值结果?

q <- lapply(1:3, function(x) x ** 2)
## returns nothing, because it is an assignment

# however, how you explain this?:

> lapply(list(1:3, 4:6, 7:9, 10:11), function(v) q <- lapply(v, function(x) x ** 2))
[[1]]
[[1]][[1]]
[1] 1

[[1]][[2]]
[1] 4

[[1]][[3]]
[1] 9


[[2]]
[[2]][[1]]
[1] 16

[[2]][[2]]
[1] 25

[[2]][[3]]
[1] 36


[[3]]
[[3]][[1]]
[1] 49

[[3]][[2]]
[1] 64

[[3]][[3]]
[1] 81


[[4]]
[[4]][[1]]
[1] 100

[[4]][[2]]
[1] 121

# while this gives the same but is logical (q is stated as return value).
> lapply(list(1:3, 4:6, 7:9, 10:11), function(v) {q <- lapply(v, function(x) x ** 2);q})
[[1]]
[[1]][[1]]
[1] 1

[[1]][[2]]
[1] 4

[[1]][[3]]
[1] 9


[[2]]
[[2]][[1]]
[1] 16

[[2]][[2]]
[1] 25

[[2]][[3]]
[1] 36


[[3]]
[[3]][[1]]
[1] 49

[[3]][[2]]
[1] 64

[[3]][[3]]
[1] 81


[[4]]
[[4]][[1]]
[1] 100

[[4]][[2]]
[1] 121

为什么在第二个表达式中,虽然innerlapply只是在函数结束时被赋值qq没有被调用,但赋值的值却被返回给了outerlapply并因此被收集?请问,有人对这种现象有解释吗?

它也适用于 =

lapply(list(1:3, 4:6, 7:9, 10:11), function(v) q = lapply(c(v), function(x) x ** 2))

[[1]]
[[1]][[1]]
[1] 1

[[1]][[2]]
[1] 4

[[1]][[3]]
[1] 9


[[2]]
[[2]][[1]]
[1] 16

[[2]][[2]]
[1] 25

[[2]][[3]]
[1] 36


[[3]]
[[3]][[1]]
[1] 49

[[3]][[2]]
[1] 64

[[3]][[3]]
[1] 81


[[4]]
[[4]][[1]]
[1] 100

[[4]][[2]]
[1] 121

回答

答案就在返回值的的赋值操作。赋值运算符<-不仅将值写入调用环境中的变量,而且实际上将赋值本身无形地返回给调用者。

请记住,R 中的所有操作实际上都是函数。当你做

x <- 3

你实际上在做

`<-`(x, 3)
`<-`(x, 3)

这不仅在调用环境中创建符号“x”并将值 3 分配给该符号,而且无形地将值 3 返回给调用者

y <- 2
y
#> [1] 2

y <- `<-`(x, 3)
y
#> [1] 3

要看到这一点,请考

y <- (x <- 4)
y
#> [1] 4
y <- (x <- 4)
y
#> [1] 4

虑:

y <- 2
y
#&
y <- x <- 5
y
#> [1] 5

gt; [1] 2

y <- `<-`(x, 3)
y
#> [

y <- x <- 5
y
#> [1] 5

1] 3

或者等效地,

事实上,由于 R 的求值顺序,我们甚至可以这样做:

这是在同一行上将多个变量设置为相同值的一种巧妙方法。

现在考虑你在你的内部使用的 lambda 函数lapply

看看当我们将此函数视为独立函数时会发生什么:

正如预测的那样,什么也没有发生。但是当我们这样做时会发生什么:

如果 func(1:3) 没有返回任何东西,那么a现在大概应该是空的。

但它不是...

因为赋值的值是无形地返回给调用者的,所以我们能够将它赋值给调用范围内的一个值。因此,做

function(v) q <- lapply(v, function(x) x ** 2)

将应用于所有列表元素的内部函数的值分配给新列表。这个列表不是隐形返回,而是正常返回。

所以这是预期的行为。

  • This is a great answer! Everyone should upvote this. I started to write this and decided it was going to take too long to explain. Well done @AllanCameron!

以上是为什么`lapply`会自动返回赋值结果?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>