【问题标题】:R lapply statement with index [duplicate]带有索引的R lapply语句[重复]
【发布时间】:2012-09-02 22:10:16
【问题描述】:

有没有办法让 lapply 语句也显示索引?更具体地说,请考虑以下示例:

mylist <- list(c(5,4),c(3,2), c(1,3))

myfunction<- function(values){
  print("Adding values: ")
  return(values[1] + values[2])
}

lapply(mylist, myfunction)

有没有办法让它打印“添加值:1”“添加值:2”等。列表中的每个元素都有一个?

谢谢!

【问题讨论】:

  • 好吧,你可以让myfunction 使用索引而不是列表项,执行print(idx),使用values = mylist[[idx] 获取值,然后执行lapply(1:length(mylist), myfunction)
  • 抱歉,但我不确定这将如何运作?在这种情况下,myfunction 只是得到一个数字,我需要它来得到一堆东西。也许您可以提供更多的伪代码?为混乱道歉!
  • 请参阅?lapply 并阅读参数说明。请注意,... 用于函数的附加参数,因此您需要在此处指定它们。

标签: r list lapply


【解决方案1】:

函数mapply 的作用类似于lapply,但允许您提供多个向量或列表。

在您的情况下,您可以创建第二个向量,与列表的长度相同,只是向上计数:

mapply(myfunction, mylist, seq_along(mylist))

让我们试试吧:

myfunction<- function(values, index){ 
  cat("Adding values (", index, "): ", values[1], "...", values[2], " = ", sum(values), "\n" )
  invisible(values[1] + values[2])
}

mylist <- list(c(5, 4), c(3, 2), c(1, 3))

mapply(myfunction, mylist, seq_along(mylist))

结果:

Adding values ( 1 ):  5 ... 4  =  9 
Adding values ( 2 ):  3 ... 2  =  5 
Adding values ( 3 ):  1 ... 3  =  4 

高级用户乐趣

只是为了好玩,仔细阅读 ?lapply 手册页会发现以下内容也有效:

myfunction<- function(values){
    print(sprintf("Adding values: %i",substitute(values)[[3]]))
    return(values[1] + values[2])
}

lapply(mylist, myfunction)

这表明可以创建一个通用函数适配器来为您的原始函数(或任何其他函数)提供索引,修改为期望第二个索引参数:

myfunction<- function(values,index){
    print(sprintf("Adding values: %i",index))
    return(values[1] + values[2])
}

现在是适配器

lapply_index_adaptor=function(f)function(x,...)f(x,substitute(x)[[3]],...)

现在是 lapply 调用,带有适配器:

lapply(mylist, lapply_index_adaptor(myfunction))

【讨论】:

  • 那是非常有见地的“仔细阅读 ?lapply”。
【解决方案2】:

您是否要求对正在发生的特定价值观和过程进行“评论”?

myfunction<- function(values){ 
  cat("Adding values: ", values[1], "...", values[2], " = ", sum(values), "\n" )
  invisible(values[1] + values[2])
}

 lapply(mylist, myfunction)

Adding values:  5 ... 4  =  9 
Adding values:  3 ... 2  =  5 
Adding values:  1 ... 3  =  4 
[[1]]
[1] 9

[[2]]
[1] 5

[[3]]
[1] 4

【讨论】:

    【解决方案3】:

    如果您要发送消息,最好使用message

    mylist <- list(c(5, 4), c(3, 2), c(1, 3))
    

    如果你想要索引(重读这可能是你想要的)

    myfunction_idx <- function(idx, x) {
        .x <- x[[idx]]
        message(sprintf("Adding values %s:", idx))
    
        sum(.x)
    }
    lapply(seq_along(mylist), myfunction_idx, x = mylist)
    
    ## Adding values 1: 
    
    ## Adding values 2: 
    
    ## Adding values 3: 
    
    ## [[1]]
    ## [1] 9
    ## 
    ## [[2]]
    ## [1] 5
    ## 
    ## [[3]]
    ## [1] 4
    ## 
    

    plyr 解决方案

    plyr 包将即时构建进度条(lapply 会更快

    library(plyr)
    llply(mylist, sum, .progress = 'text')
    

    【讨论】:

    • 不,这不完全是。我自己的例子要复杂得多。我无法输入关于 myfction 输入内容的 cat 消息,因为这对用户没有帮助。每个列表元素本身都有许多使用的子元素。我特别希望它打印“处理列表元素 1”、“处理列表元素 2”等......这样用户就知道它在 lapply 中的距离。谢谢!
    • 我已经编辑了回复。这是你想要的更多吗?
    • 不完全,但这真的很整洁!感谢您向我展示 llply!
    猜你喜欢
    • 2015-04-18
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 2020-02-26
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    相关资源
    最近更新 更多