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

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

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


person Sergey Samusev    schedule 14.04.2013    source источник
comment
вы должны сохранить его в переменной. x <- getTitles(mypages).   -  person Arun    schedule 14.04.2013


Ответы (4)


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

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

person Dirk Eddelbuettel    schedule 14.04.2013
comment
Почему глобальное присваивание — зло, а не функционально? - person vashts85; 28.02.2017
comment
Другие рекомендуют использовать assign вместо <<-. На аналогичный вопрос есть хороший ответ здесь< /а> - person Alison Bennett; 07.11.2017

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

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)
person flodel    schedule 14.04.2013

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

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

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

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

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

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

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

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

person Teng L    schedule 13.07.2017