簡體   English   中英

R 子集嵌套列表,選擇多個條目

[英]R Subsetting nested lists, select multiple entries

我經常使用大型數據集,這導致我有時會創建嵌套列表以減少環境中的對象。

當對這樣的列表進行子集化並想要在所有步驟中轉到第一個條目時,它看起來像這樣:

llra[[1]][[1]][[1]]

在我當前的一些腳本中,這些腳本中的數據與列表中最后一步的每個條目都具有可比性一致。 如果我想比較這些或進行計算,它看起來像這樣:

mean(llra[[1]][[1]][[1]], llra[[1]][[2]][[1]], llra[[1]][[3]][[1]])

有沒有辦法以不同的方式對它們進行子集化,以便我可以這樣寫:

mean(llra[[1]][[c(1:3)]][[1]])

謝謝你的幫助!

創建一個小的輔助函數。 這將創建一個索引網格並提取每個索引。 最后它會取消列出結果。 不使用任何包。

unravel <- function(L, ...) {
  if (...length()) L <-
    apply(expand.grid(...), 1, function(ix) L[[ix]], simplify = FALSE)
  unlist(L)
}

# test

L <- list(a = list(b = list(1:3, 4:5), c = list(11:12, 20:25)))

# Example 1

mean(unravel(L, 1, 1:2, 1))
## [1] 5.8

# check
mean(c(L[[1]][[1]][[1]], L[[1]][[2]][[1]]))
## [1] 5.8

# Example 2

mean(unravel(L, 1, 1, 1:2))
## [1] 3

# check
mean(c(L[[1]][[1]][[1]], L[[1]][[1]][[2]]))
## [1] 3

更新

對 unravel 進行概括,使其不假設三個級別或將哪個級別指定為標量或向量索引。

您可以使用purrr::map

mean(map_dbl(1:3, ~llra[[1]][[.x]][[1]]))

由於您沒有給我們提供示例數據集,我為您創建了它:

ua <- list(
    list(
        list(1),
        list(9),
        list(3),
        list(3)
        )
    )

您可以創建一個表達式以在循環中使用它:

e <- expression(ua[[1]][[j]][[1]])

我對第一個和最后一個索引以及列表名稱進行了硬編碼,但如果需要,您可以更改它。 就像現在一樣,在評估e期間將在全局環境中找到變量ua

在循環中對此進行評估將為您提供內部列表值。 變量j將在 lambda 函數的本地環境中找到 ( \\(j) {eval(e) }

sapply(1:4, \(j) { eval(e) })

# [1] 1 9 3 3

你可以調用任何你想要的函數:

cat(mean(sapply(1:4, \(j) { eval(e) })), 'millions \u2620') 

# 4 millions ☠

我認為必須有另一種方式。 但是,至少,使用此表達式您可以編寫或多或少靈活的函數來處理此類情況。 或者你可以找到完全不同的,並且可能更簡單的方法來做同樣的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM