请考虑以下代码:
foo = list("First List", 1, 2, 3)
bar = function(x) {
cat("The list name is:", x[[1]], "\nThe items are:\n")
for (i in 2:length(x))
cat(x[[i]], "\n")
}
bar(foo)
结果将是:
The list name is: First List
The items are:
1
2
3
现在考虑传递一个没有项目但名称的列表:
baz = list("Second List")
bar(baz)
结果将是:
The list name is: Second List
The items are:
Error in x[[i]] : subscript out of bounds
错误是因为2:length(x)
会为后一种情况c(2, 1)
生成一系列bar(baz)
,因此它会尝试访问baz[2]
并且它不存在。
如何在R?{/ p>中的for
循环中简单地防止这种不需要的反向迭代
答案 0 :(得分:9)
seq_along
帮助的是:
bar <- function(x) {
cat("The list name is:", x[[1]], "\nThe items are:\n")
for (i in seq_along(x[-1])) cat(x[[i+1]], "\n") ### Edit ###
}
结果:
bar(foo)
The list name is: First List
The items are:
First List
1
2
3
bar(baz)
The list name is: Second List
The items are:
Second List
当然,最好不要使用for
循环,但lapply
或家庭:
bar <- function(x) {
cat("The list name is:", x[[1]], "\nThe items are:\n")
lapply(x[-1], function(xx)cat(xx, "\n"))
invisible(NULL)
}
bar(foo)
The list name is: First List
The items are:
1
2
3
bar(baz)
The list name is: Second List
The items are:
答案 1 :(得分:4)
无需遍历列表索引,您只需循环遍历子列表:
> bar = function(x) {
+ cat("The list name is:", x[[1]], "\nThe items are:\n")
+ for (i in x[-1])
+ cat(i, "\n")
+ }
如果列表中有单个项目,则子列表将为空,并且将跳过for循环。
编辑:正如GavinSimpson指出的那样,这很有效,因为你的特殊情况并不需要循环索引。如果完全需要索引,那么你必须循环seq_along(x[-1])
而不是x[-1]
,正如Andrie所示。
答案 2 :(得分:2)
我认为正确答案是:对您的功能进行输入验证。而不是创建意大利面条代码来“解决”这种行为,测试输入变量的长度,或检查每个元素的typeof
等。
在您的示例中,简单的if (length(x)<2) #skip the loop section of code
就足够了。