Печать на консоли R изнутри функции - PullRequest
0 голосов
/ 07 июня 2018

Я хочу изменить поведение печати консоли в функции R, чтобы вернуть то же поведение, что и в глобальной среде.

Несмотря на то, что вы можете вызвать browser(), чтобы войти в среду функций и получить доступ к локальным переменным, я просто хочу получить выражения для вывода на консоль.

Цель состоит в том, чтобы иметь гибкий ибыстрый способ оценить множество (десятки) выражений для проверки кода и понимания статистических свойств промежуточного вывода.Я хочу сделать это на лету, без необходимости входить в функцию с помощью отладчика, поскольку это требует дополнительного ручного управления, а также без необходимости записывать избыточные операторы, такие как print("x^2"); print(x^2), что я мог бы сделать, но позже впроцесс разработки кода для более постоянных проверок кода.

Я имею в виду следующее: напишите функцию log.to.console(), чтобы получилось следующее:

myfunlog = function(x){
  log.to.console()
  a1 = sqrt(x)
  a2 = exp(x)
  a1;a2;log(x);x^2
  return(a1*a2)
}
ans = myfunlog(2)
[1] a1
[1] 1.414214
[1] a2
[1] 7.389056
[1] log(x)
[1] 0.6931472
[1] x^2
[1] 4

У меня есть решение, котороеэто не совсем то, что я искал, но, благодаря продвинутым R-страницам Хэдли для выражений и областей видимости, я разработал эту функцию:

print.to.console = function(...){
  dots = pryr::named_dots(...)
  p = parent.frame()
  for( dot in dots){
    print(dot)
    print(eval(dot, envir = p))
  }
}

myfunprint = function(x){
  a1 = sqrt(x)
  a2 = exp(x)
  print.to.console(
    a1, a2, log(x), x^2
  )
  return(a1*a2)
}
ans = myfunprint(2)
# Which gives the output I want:
a1
[1] 1.414214
a2
[1] 7.389056
log(x)
[1] 0.6931472
x^2
[1] 4

Обновление: теперь я могу вызывать это с помощью явной области видимости только с одной функциейзвоните, тогда как раньше я должен был использовать environment(print.to.console) = environment() в myfunprint().Однако я все же предпочел бы выяснить, как реализовать функциональность log.to.console(), описанную выше.Есть идеи?

1 Ответ

0 голосов
/ 07 июня 2018

Я предлагаю создать именованный список с символьными метками и значениями

prtplus <- function(...){ dots <- substitute(list(...))[-1]
    anames <-  sapply(dots, deparse); setNames( list(...), anames) }

Начиная с globalenv(), где у меня были разные константы.

print( prtplus( p.lh, p.ml, p.hm) )
$p.lh
[1] 0.1

$p.ml
[1] 0.3

$p.hm
[1] 0.5

Это print было лишним из globalenv(), но было бы необходимо изнутри функции:

myfunlog = function(x){

   a1 = sqrt(x)
   a2 = exp(x)
   print( prtplus(
     a1, a2, log(x), x^2
   ))
   return(a1*a2)
 }

 ans = myfunlog(2)
$a1
[1] 1.414214

$a2
[1] 7.389056

$`log(x)`
[1] 0.6931472

$`x^2`
[1] 4

Вы также можете встроить print в prtplus:

prtplus <- function(...){ dots <- substitute(list(...))[-1]
   anames <-  sapply(dots, deparse); print(setNames( list(...), anames)) }

Есливам не нравится печатное представление списка R с обратными галочками имен, тогда это дает именно запрашиваемый «взгляд»:

prtplus <- function(...){ dots <- substitute(list(...))[-1]
   anames <-  sapply(dots, deparse)
   vals <- setNames( list(...), anames)
   for(i in seq_along(vals)){ 
        cat( c( names(vals)[i], "\n", round( vals[[i]],6),"\n") ) }
                         }

 ans = myfunlog(2)
#----output to console---
a1 
 1.414214 
a2 
 7.389056 
log(x) 
 0.693147 
x^2 
 4 
...