我正在将一个函数应用于列表的元素。
列表中有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
任何有见地的想法?
答案 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"