如何使在函数内创建的对象可在外部使用
Posted
技术标签:
【中文标题】如何使在函数内创建的对象可在外部使用【英文标题】:How to make object created within function usable outside 【发布时间】:2013-04-06 08:08:05 【问题描述】:我创建了一个生成矩阵的函数,但我不知道如何使该函数的输出在函数环境之外可用,以便例如将其保存在 csv 文件中。
我的函数代码如下:
创建的函数从特定站点获取 url 并返回页面标题:
getTitle <- function(url)
webpage <- readLines(url)
first.row <- webpage[1]
start <- regexpr("<title>", first.row)
end <- regexpr("</title>", first.row)
title <- substr(first.row,start+7,end-1)
return(title)
创建的函数采用 url 向量并返回 n*2 矩阵,其中包含 url 和页面标题:
getTitles <- function(pages)
my.matrix <- matrix(NA, ncol=2, nrow=nrow(pages))
for (i in seq_along(1:nrow(pages)))
my.matrix[i,1] <- as.character(pages[i,])
my.matrix[i,2] <- getTitle(as.character(pages[i,]))
return(my.matrix)
print(my.matrix)
在 http://goo.gl/D9lLZ 的示例文件上运行此函数后,我使用 read.csv 函数导入并命名为“mypages”,得到以下输出:
getTitles(mypages)
[,1] [,2]
[1,] "http://support.google.com/adwords/answer/1704395" "Create your first ad campaign - AdWords Help"
[2,] "http://support.google.com/adwords/answer/1704424" "How costs are calculated in AdWords - AdWords Help"
[3,] "http://support.google.com/adwords/answer/2375470" "Organizing your account for success - AdWords Help"
这正是我所需要的,但我希望能够将此输出导出到 csv 文件或重复使用以进行进一步的操作。但是,当我尝试打印(my.matrix)时,我收到一条错误消息“错误:找不到对象'my.matrix'”
我觉得这是我知识上相当基本的差距,但是有一段时间没有使用 R 并且无法解决这个问题。
谢谢! 谢尔盖
【问题讨论】:
你必须将它保存到一个变量中。x <- getTitles(mypages)
.
【参考方案1】:
函数结束时可以return
结果。
首先定义函数:
getRangeOf <- function (v)
numRange <- max(v) - min(v)
return(numRange)
然后调用它并将输出分配给一个变量:
scores <- c(60, 65, 70, 92, 99)
scoreRange <- getRangeOf(scores)
从这里开始在环境中使用scoreRange
。 在您定义的函数中的任何变量或嵌套函数都不能被外部访问,当然,除非您使用<<-
来分配全局变量。所以在这个例子中,你不能从外部看到 numRange
是什么,除非你把它变成全局的。
通常,在早期尽量避免使用全局变量。变量是“封装的”,因此我们知道在当前上下文(“环境”)中使用了哪个变量。全局变量更难驯服。
【讨论】:
【参考方案2】:您不能只使用<<-
将对象分配给工作区吗?以下代码适用于我并保存 amort_value
对象。
amortization <- function(cost, downpayment, interest, term)
amort_value <<- (cost)*(1-downpayment/100)*(interest/1200)*((1+interest/1200)^(term*12))/((1+interest/1200)^(term*12)-1)
sprintf("$%.2f", amort_value)
amortization(445000,20,3,15)
amort_value
【讨论】:
【参考方案3】:一点关于函数式编程的知识。首先,当你定义你的函数时:
getTitles <- function(pages)
[...]
return(my.matrix)
print(my.matrix)
知道当函数被调用时,它永远不会到达print
语句。相反,它将在之前以return
退出。所以你可以删除那个print
声明,它没用。
现在是更重要的东西。在你的函数中,你定义并返回my.matrix
。该对象只存在于函数范围内:函数退出时,返回的是一个未命名的对象(而my.matrix
丢失了。)
在你的会话中,当你打电话时
getTitles(mypages)
打印结果是因为您没有分配它。相反,您应该这样做:
out.matrix <- getTitles(mypages)
现在将不会打印结果,但您绝对可以通过在一行上输入print(out.matrix)
或仅输入out.matrix
来打印。由于您已将结果存储在一个对象中,您现在可以重用它以进行进一步的操作。
如果它可以帮助你掌握概念,这和从命令行调用c()
函数是一样的:
c(1, 5, 2) # will return and print a vector
x <- c(1, 5, 2) # will return and assign a vector (not printed.)
奖励:真的,我认为您不需要定义getTitles
,但您可以使用*apply
函数之一。我会试试这个:
url <- as.character(mypages)
title <- sapply(url, getTitle)
report <- data.frame(url, title)
write.csv(report, file = "report.csv", row.names = FALSE)
【讨论】:
【参考方案4】:这很简单:使用<<-
分配给全局变量。
但话又说回来,全局分配是邪恶的,而且不起作用。也许你宁愿回来
包含您的函数的多个结果的列表?查看您的代码,似乎您的第二个函数可能会混淆return
和print
。确保返回正确的数据结构。
【讨论】:
为什么全局赋值是邪恶的而不是功能性的? 其他人推荐使用assign,而不是<<-
。类似问题有一个很好的答案here以上是关于如何使在函数内创建的对象可在外部使用的主要内容,如果未能解决你的问题,请参考以下文章