如何在列表中循环并访问名称和属性?

时间:2011-09-20 07:25:41

标签: r

我正在将一个函数应用于列表的元素。

列表中有names,所以从某种意义上说,每个元素都有自己的名称,但是一旦lapply函数已经从列表中提取/分离了元素,我该如何访问它?

一些虚拟数据(作为内部函数,我在这里滥用dput):

r <- list(a=structure(1:4, unit="test"), b='abc')
lapply(r, dput)

我在这里观察到的是dput接收列表中的对象,就像使用[[访问一样,被剥夺了它们在包含列表中的名称。

所以我想我会放弃使用apply系列中的函数并写一个循环的想法,但我并不特别喜欢这个想法,它要求我构造完整函数的结果。< / p>

result <- list()
for (name in names(r)) {
  print(name)
  result[[name]] <- dput(r[[name]])
}
result

任何有见地的想法?

2 个答案:

答案 0 :(得分:5)

您可以在使用lapply时模拟循环背后的想法,方法是将数字向量传递给lapply,然后将其用作索引以从所需列表中提取元素。这可能没有意义,但希望这个例子说明了我的意思:

lapply(seq_along(r), function(i)dput(r[i]))

structure(list(a = structure(1:4, unit = "test")), .Names = "a")
structure(list(b = "abc"), .Names = "b")
[[1]]
[[1]]$a
[1] 1 2 3 4
attr(,"unit")
[1] "test"



[[2]]
[[2]]$b
[1] "abc"

关键的想法是seq_along(x)返回与x长度相同的序列。例如:

> seq_along(r)
[1] 1 2

有关详细信息,请参阅?seq_along


修改

这似乎比按名称索引要快得多:

library(rbenchmark)
benchmark(
  xx <- lapply(names(r), function(i)dput(r[i])),
  yy <- lapply(seq_along(r), function(i)dput(r[i])),
  replications=10000)

                                                test replications elapsed relative user.self
1     xx <- lapply(names(r), function(i) dput(r[i]))        10000    1.95 1.026316      1.70
2 yy <- lapply(seq_along(r), function(i) dput(r[i]))        10000    1.90 1.000000      1.66
  sys.self user.child sys.child
1     0.00         NA        NA
2     0.01         NA        NA

答案 1 :(得分:2)

您可以使用mapply

dummy <- function(value, name) {
    list(
        name_of_element = name,
        value_of_element = value
    )
}
str(mapply(dummy, r, names(r), SIMPLIFY=FALSE))
# List of 2
 # $ a:List of 2
  # ..$ name_of_element : chr "a"
  # ..$ value_of_element: atomic [1:4] 1 2 3 4
  # .. ..- attr(*, "unit")= chr "test"
 # $ b:List of 2
  # ..$ name_of_element : chr "b"
  # ..$ value_of_element: chr "abc"