【问题标题】:Iterate over key/value pair from a list()从 list() 迭代键/值对
【发布时间】:2011-05-28 20:35:48
【问题描述】:

我想知道如何从 R 中的列表对象中迭代键/值对,如下例所示:

toto <- list(a="my name is",b="I'm called",c="name:")
myfun <- function(key,value) paste(value,key)
for( key in names(toto) ) toto[key] <- myfun(key,toto[[key]])

有没有办法避免 for 循环(使用 lapply() 等)。会不会更快?

谢谢!

【问题讨论】:

  • 请记住,lapply 仍然涉及迭代,虽然它可能比 for 快​​一点,但情况并非总是如此(而且它当然不等同于矢量化功能)。 stackoverflow.com/questions/2275896/…

标签: r


【解决方案1】:

这应该为你做:

do.call(paste, list(toto, names(toto) ))

【讨论】:

  • 这里不需要 do.call。 paste(toto,names(toto)) 工作得很好。而且在我眼里更加优雅。
【解决方案2】:

最好的解决方案是直接调用paste 而无需循环(它已经被矢量化了):

> paste(toto, names(toto))
[1] "my name is a" "I'm called b" "name: c"  

一个类似的问题previously asked on R-Help,有几个创造性的解决方案。 lapply 无法在函数中显示名称。这个函数是由 Romain Francois 根据 Thomas Lumley 的一些东西提供的:

yapply <- function(X,FUN, ...) { 
  index <- seq(length.out=length(X)) 
  namesX <- names(X) 
  if(is.null(namesX)) 
    namesX <- rep(NA,length(X))

  FUN <- match.fun(FUN) 
  fnames <- names(formals(FUN)) 
  if( ! "INDEX" %in% fnames ){ 
    formals(FUN) <- append( formals(FUN), alist(INDEX=) )   
  } 
  if( ! "NAMES" %in% fnames ){ 
    formals(FUN) <- append( formals(FUN), alist(NAMES=) )   
  } 
  mapply(FUN,X,INDEX=index, NAMES=namesX,MoreArgs=list(...)) 
}

这是一个使用示例:

> yapply(toto, function( x ) paste(x, NAMES) )
             a              b              c 
"my name is a" "I'm called b"      "name: c" 

【讨论】:

  • mapply 对 OP 案例的基本使用将是 mapply(myfun, key=names(toto), value=toto)
  • @Marek 好点!我确实认为值得覆盖的不仅仅是粘贴,以防 OP 考虑到这个问题的其他用途。我还要注意,这实际上是 yapply 在幕后所做的(请参阅该函数的最后一行)。
  • 我更喜欢 mapply 任何一天而不是 yapply 以便任何体面的 R 程序员都可以轻松理解您在做什么,因为它是一个“标准”应用函数。
【解决方案3】:

R 人通常不喜欢直接回答一个简单的问题。

这是您可以迭代列表中的键/值对的方法:

for (name in names(myList)) {
  print(name)
  print(myList[[name]])
}

【讨论】:

  • 这应该是公认的答案:)
猜你喜欢
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 2020-06-02
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多