如何无形地返回列表的一部分

时间:2014-11-21 19:38:28

标签: r user-defined-functions

我可能会在这里找到一些非常简单的东西。

如何在R中创建一个用户定义的函数,返回一个不可见的元素列表?

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

我希望up打印up$sunup$clouds,而不是其他两个元素。然而,我仍然希望up成为所有四个元素的列表:

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

3 个答案:

答案 0 :(得分:5)

您可以制作S3打印方法

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

您可以看到只会影响其打印方式

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"  

这是将类分配给对象的另一种方法

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

print.mysky将被分派,因为对象的类是“mysky”

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

如果要调度默认打印方法,可以直接调用它(print.default(sky()))或unclass对象

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

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

答案 1 :(得分:1)

这使用print来完成工作。它比cat具有“理解”列表的优势:

 sky <- function(){
    x <- list(sun = 1, clouds = 4, birds =2, moon = 0)
    print(x[1:2])
    invisible(x)
 }
#----------- 
> up <- sky()
$sun
[1] 1

$clouds
[1] 4

> z <- sky()
$sun
[1] 1

$clouds
[1] 4

> print(z)
$sun
[1] 1

$clouds
[1] 4

$birds
[1] 2

$moon
[1] 0

通常一个人使用cat如果目标是将某些东西放在一个不是值的控制台

sky <- function(){
x <- list(sun = 1, clouds = 4, birds =2, moon = 0)
sapply(x[1:2], cat, "\n")
invisible(x)
}

up <- sky()
1
4

答案 2 :(得分:-1)

为什么不用JQuery做这件事。将元素放在<li>中并使用JQuery隐藏和显示元素。您可以显示前两个,或显示所有其余部分。我希望这个机制适合你。

<ul class="collapse">
     <li>sun</li>
     <li>clouds</li>
     <li>birds</li>
     <li>moon</li>
</ul>

JS

$(document).ready(function () {
     $('ul.collapse').wrap('<div class="collapseWrapper" />');
     $('div.collapseWrapper').css({ 'height' : '45px' }).after('<a href="#" class="collapseMore">view details . . .</a>');

     $('a.collapseMore').click(function () {
          if ($(this).hasClass('expanded')) {
               $(this).prev().animate({ height: '45px' }, 500);
               $(this).text('view details . . .').removeClass('expanded');
          }
          else {
               $(this).prev().animate({ height: $(this).prev().find( 'ul.collapse' ).outerHeight(true) }, 500);
               $(this).text('hide details . . .').addClass('expanded');
          }
          return false;
     });
});

CSS:

ul.collapse{  }
ul.collapse li {  }
div.collapseWrapper { overflow: hidden; }
a.collapseMore {  }
a.collapseMore:hover {  }