Как создать объект, созданный внутри функции, полезной вне

Я создал функцию, которая в результате создает матрицу, но я не могу понять, как сделать вывод этой функции полезной вне среды функций, чтобы я мог, например, сохранить ее в файле 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)
}

созданная функция, которая берет вектор urls и возвращает матрицу 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 некоторое время и не мог решить этого.

Спасибо! Сергей

Ответ 1

Это легко: используйте <<- для назначения глобальному.

Но опять же глобальное задание является злым и не функциональным. Может быть, вы скорее вернетесь список с несколькими результатами от вашей функции? Глядя на ваш код, кажется, что ваша вторая функция может смутить return и print. Убедитесь, что вы вернули правильную структуру данных.

Ответ 2

Немного о функциональном программировании. Прежде всего, когда вы определяете свою функцию:

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)

Ответ 3

Не можете ли вы использовать <<-, чтобы присвоить ему объект рабочей области? Следующий код работает для меня и сохраняет объект 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

Ответ 4

В конце функции вы можете return получить результат.

Сначала определите функцию:

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

Затем вызовите его и назначьте вывод переменной:

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

Здесь используется scoreRange в среде. Любые переменные или вложенные функции внутри ваша определенная функция недоступна для внешней стороны, если, конечно, вы не используете <<- для назначения глобальной переменной. Итак, в этом примере вы не можете видеть, что numRange находится снаружи, если вы не сделаете его глобальным.

Обычно старайтесь избегать глобальных переменных на ранней стадии. Переменные "инкапсулируются", поэтому мы знаем, какой из них используется в текущем контексте ( "среда" ). Глобальные переменные сложнее приручить.