【问题标题】:How to invisibly return a portion of a list如何无形地返回列表的一部分
【发布时间】:2015-01-20 01:12:24
【问题描述】:

我可能在这里遗漏了一些非常简单的东西。

如何在 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"

【问题讨论】:

  • 您要求对up 进行“调用”,这意味着它是一个函数,但随后您要求它像数据对象一样显示名称。
  • 好点。我刚刚纠正了这一点。
  • 元素“不可见”是什么意思? up$birds 会返回什么?
  • up$birds 返回 2。但是当您打印 up 时,up$birdsup$moon 未列出。作为另一个示例,如果a 属于"lm" 类,则print(summary(a)) 返回names(summary(a)) 中元素的不完整列表。这是怎么做到的?

标签: r user-defined-functions


【解决方案1】:

你可以做一个 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

【讨论】:

    【解决方案2】:

    这使用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
    

    【讨论】:

      【解决方案3】:

      你为什么不用 JQuery 来做这件事。将元素放入&lt;li&gt; 并使用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 {  }
      

      【讨论】:

        猜你喜欢
        • 2020-12-16
        • 1970-01-01
        • 2019-04-28
        • 2021-06-11
        • 2022-01-06
        • 1970-01-01
        • 2016-12-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多