Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to invisibly return a portion of a list

I might be missing something very simple here.

How do I create a user-defined function in R that returns a list where some elements are invisible?

sky <- function(){
list(sun = 1, clouds = 4, birds =2, moon = 0)
}

up <- sky()

up
#$sun
#[1] 1
#
#$clouds
#[1] 4
#
#$birds
#[1] 2
#
#$moon
#[1] 0

I would like up to print up$sun and up$clouds but not the other two elements. Yet, I still want up to be a list of all four elements:

names(up)
#[1] "sun"    "clouds" "birds"  "moon"
like image 716
sdg238 Avatar asked Nov 21 '14 19:11

sdg238


1 Answers

You could make an S3 print method

sky <- function(){
  structure(list(sun = 1, clouds = 4, birds =2, moon = 0), class="mysky")
}
print.mysky <- function(x, ...) print(x[1:2])

sky()
#$sun
#[1] 1
#
#$clouds
#[1] 4

You can see that that only affects how it is printed

str(sky())
#List of 4
# $ sun   : num 1
# $ clouds: num 4
# $ birds : num 2
# $ moon  : num 0
# - attr(*, "class")= chr "mysky"

names(sky())
#[1] "sun"    "clouds" "birds"  "moon"  

Here's another way to assign a class to an object

sky <- function(){
  out <- list(sun = 1, clouds = 4, birds =2, moon = 0)
  class(out) <- "mysky"
  out
}

print.mysky will be dispatched since the object's class is "mysky"

class(sky())
#[1] "mysky"

if you want to dispatch the default print method you can either call it directly (print.default(sky())), or unclass the object

#print.default(sky())
unclass(sky())

#$sun
#[1] 1
#
#$clouds
#[1] 4
#
#$birds
#[1] 2
#
#$moon
#[1] 0
like image 151
GSee Avatar answered Oct 11 '22 19:10

GSee