2016-09-30 107 views
0

我创建了以下函数来在名为“饭食”的字符串矢量上附加新字符串。但是,当我使用此函数将字符串输入附加到我的“膳食”向量时,它不起作用。这个R函数为什么不起作用?

add <- function(str) { 
     meals <- append(meals, as.character(str)) 
    } 
+1

这两个评论都错过了这一点。该功能将起作用,但需要以功能性方式应用,即:'饭食< - 添加(c(“午餐”,“晚餐”))' –

+2

因为它会返回'append'调用的值。尝试它并阅读'?'< - '' –

+0

我把这个问题搁置的问题。这不是一个错字。至少有两位评论者(现在已经删除了他们的评论)展示了R功能如何返回值,并且还由于也错过了这个方面的两个答案展示了这一点。它可以作为一个有用的例子,但现在封闭似乎正在把它扫到地毯下。仅仅因为提问者不理解这一点并不是一个微不足道的问题。这实际上是一个相当深刻的问题,它的正确答案表明了R和大多数其他计算机语言之间的根本区别。 –

回答

0

你需要确保你分配功能输出到你的情况的变量尝试一些像这样的(3个可能的解决方案):

## longest/redundant 
add <- function(str) { 
    meals <- append(meals, as.character(str)) 
    return(meals) 
} 

## alternative 
add2 <- function(str) { 
    meals <- append(meals, as.character(str)) 
} 

## simplest 
add3 <- function(str) { 
    append(meals, as.character(str)) 
} 

meals <- c("chx","beef","pork") 
str1 <- c(1, 2, 3) 

newVar <- add(str1) 
print(newVar) 
[1] "chx" "beef" "pork" "1" "2" "3" 

newVar2 <- add2(str1) 
print(newVar2) 
[1] "chx" "beef" "pork" "1" "2" "3" 

newVar3 <- add3(str1) 
print(newVar3) 
[1] "chx" "beef" "pork" "1" "2" "3" 

你也可以考虑一个简单的解决方案:

c(meals, str1)这将返回相同的确切的东西。通常仅在需要使用after参数时才使用append

+0

在这种情况下使用return是不必要的。这个答案会打印该值,但会让用户改变str。核实。它保持不变。 –

+0

良好的通话,更新它。 – TBSRounder

+0

[有趣的讨论是否完全使用返回()或不](http://stackoverflow.com/questions/11738823/explicitly-calling-return-in-a-function-or-not) – TBSRounder

0

它不起作用?

有一点需要考虑:函数的输出是函数的最后一行。例如:

x.plus.3 <- function(x){ 
     s <- x+3 
} 
x.plus.3(2) 
# nothing is printed 

这是一个有效的函数,但如果运行将没有输出,因为所有函数都将x + 3存储到对象s中。

但是,如果我将其更改为:

x.plus.3 <- function(x){ 
     s <- x+3 
     s 
} 
x.plus.3(2) 
[1] 5 # i get the result printed 

所以,你需要为了得到它,使之功能外增加餐点的最后一行在你的函数。

0

这里的问题是变量作用域。变量meals存在于您正在使用它的全局环境中。当你运行你的函数时,函数环境中没有meals变量,所以它从全局环境继承该变量。但是,当它修改变量时,它会在函数环境内创建新版本。该函数然后可以使用该修改后的版本,但不会从全局环境中更改meals变量。

所以,你可以使用此功能,因为它是目前写的,只是结果保存到meals像这样:

meals <- add("Steak") 

的返回值是不可见的,当你将它保存到一个变量,在结束你的功能,但它仍然输出(如lmhist的完整结果,只有在将它们保存到新变量时才可以访问)。这就是为什么总是习惯于使用明确的returninvisible声明结束函数的习惯。

我的猜测是,你来自一种不同的编程语言,在函数内部改变一个全局变量会改变全局变量。该行为通过明确告诉R用<<-覆盖该环境行为,该行为将当前环境(而不是仅在其内部)之外的值分配给该环境行为。例如,这样的:

add <- function(str) { 
    meals <<- append(meals, as.character(str)) 
} 

meals <- "Steak" 

add("Chicken") 

meals 

结果meals同时持有“牛排”和“鸡” - 你想要的行为。 但是在,这通常是一个坏主意。有时候这种行为很好,但事实上它与R通常的运作方式有很大的不同,这就给错误带来了很多机会。我偶尔使用这个方法来避开范围问题(通常在shiny工作,需要改变整个会议的内容,而不仅仅是当前用户),但我尽量避免它。

我会鼓励你,相反,只需要使用建筑:

meals <- append(meals, str) 

直接,而不是试图在工作这么不同于标准的R方法的自定义函数来包装这个。