web-dev-qa-db-ja.com

関数内で作成されたオブジェクトを外部で使用可能にする方法

結果として行列を生成する関数を作成しましたが、この関数の出力を関数環境外で使用できるようにする方法がわからないため、たとえば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のベクトルを受け取り、URLとページタイトルを含むn * 2マトリックスを返す関数を作成しました。

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で作業しておらず、解決できませんでした。

ありがとう!セルゲイ

20
Sergey Samusev

それは簡単です。グローバルへの割り当てに<<-を使用します。

しかし、再び、グローバル割り当ては悪であり、機能的ではありません。たぶん、あなたはむしろあなたの関数からいくつかの結果を含むリストを返したいですか?コードを見ると、2番目の関数がreturnprintを混同しているようです。正しいデータ構造を返すようにしてください。

27

関数型プログラミングについて少し。まず、関数を定義するとき:

_getTitles <- function(pages) {
  [...]
  return(my.matrix)
  print(my.matrix)
}
_

関数が呼び出されたときに、printステートメントに到達しないことを知ってください。代わりに、returnで直前に終了します。そのため、そのprintステートメントを削除できますが、それは無意味です。

今、より重要なもの。関数内で、_my.matrix_を定義して返します。オブジェクトは関数のスコープ内にのみ存在します。関数が終了すると、返されるのは名前なしオブジェクトです(そして_my.matrix_は失われます)。

あなたのセッションで、あなたが電話するとき

_getTitles(mypages)
_

結果が割り当てられなかったため、結果が出力されます。代わりに、次のことを行う必要があります。

_out.matrix <- getTitles(mypages)
_

これで結果は出力されなくなりますが、1行に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)
_
17
flodel

<<-を使用して、オブジェクトをワークスペースに割り当てることはできませんか?次のコードは私のために機能し、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
7
vashts85

関数の最後で、結果をreturnできます。

最初に関数を定義します:

getRangeOf <- function (v) {
    numRange <- max(v) - min(v)
    return(numRange)
}

次に、それを呼び出して、出力を変数に割り当てます。

scores <- c(60, 65, 70, 92, 99)
scoreRange <- getRangeOf(scores)

ここからは、環境でscoreRangeを使用します。変数またはネストされた関数within定義された関数は、もちろん<<-を使用してグローバル変数を割り当てない限り、外部からアクセスできません。したがって、この例では、グローバルにしない限り、numRangeが外部から何であるかを見ることができません。

通常、早い段階でグローバル変数を避けるようにしてください。変数は「カプセル化」されているため、現在のコンテキスト(「環境」)でどの変数が使用されているかがわかります。グローバル変数を飼いならすのは難しいです。

6
Teng L