提问人:David 提问时间:11/5/2022 最后编辑:David 更新时间:11/5/2022 访问量:34
为什么函数有时只是 R 中的第一类变量?从内置数据结构中使用它们会导致“错误:尝试应用非函数”
Why are functions only sometimes first class variables in R? Using them from built-in data structures causes "Error: attempt to apply non-function"
问:
我正在尝试了解第一类函数在 R 中是如何工作的。我明白函数在R语言中是第一类的,但是在应用这种理解时,我感到非常失望。当函数保存到列表中时,无论是普通列表、向量还是字典样式列表或向量,它都不再可调用,从而导致以下错误:
Error: attempt to apply non-function
例如:
print_func <- function() {
print('hi')
}
print_func()
[1] "hi"
my_list = list(print_func)
my_list[0]()
Error: attempt to apply non-function
my_vector = c(print_func)
my_vector[0]()
Error: attempt to apply non-function
my_map <- c("a" = print_func)
my_map["a"]()
Error: attempt to apply non-function
那么为什么会这样呢?实际上并非在所有情况下都将函数视为第一类成员,还是有其他原因发生这种情况?
我看到 R 向量也会对嵌套数组做意想不到的事情(对我来说 - 也许不适合有经验的 R 用户):
nested_vector <- c("a" = c("b" = 1))
nested_vector["a"]
<NA>
NA
nested_vector["a.b"]
a.b
1
在这里,“a.b”可能指的是键“a”下键“b”的子成员,这对我来说是有道理的。但显然,当尝试将上层键称为“a”时,这种逻辑就消失了。
答:
1赞
B. Christian Kamgang
11/5/2022
#1
R 是从 1 开始的;因此,您使用索引 1(而不是像 Python 中的 0)来引用向量的第一个元素。
有两种方法可以访问列表元素:
- 在保留列表的同时访问列表元素(返回包含所需元素的列表)
- 从列表中拉出元素
在第一种情况下,子集是使用一对括号 () 完成的,您将始终得到一个列表。请注意,这与 python 不同,在 python 中,只有当您选择多个元素 (; return 而不是像 R 这样的单元素列表,而返回一个列表)。[]
lst = [fun1, fun2]
lst[0]
fun1
lst[0:2]
在第二种方法中,子集是使用双括号 () 完成的。你基本上把一个元素完全从列表中拉出来;更像是在 Python 中将一个元素从列表中子集出来。[[]]
print_func <- function() {
print('hi')
}
print_func()
my_list = list(print_func)
mode(my_list[1]) # return a list (not a function); so, it's not callable
[1] "list"
mode(my_list[[1]]) # return a function; so, it's callable
[1] "function"
my_list[1]() # error
my_list[[1]]() # works
[1] "hi"
#
my_vector = c(print_func)
mode(my_vector) # a list, so, not callable
[1] "list"
my_vector[1]() # error because it returns a list and not a function
my_vector[[1]]() # works
[1] "hi"
当使用名称进行子集时,适用单括号和双括号对的相同逻辑
my_map <- c("a" = print_func)
mode(my_map) # list, so, not callable
[1] "list"
my_map["a"]() # error
my_map[["a"]]() # works
[1] "hi"
评论
[[
[