簡體   English   中英

使用lapply基於列表來查找具有通用名稱的所有數據幀

[英]rbind all data frames with common names based on list using lapply

我有幾個這樣命名的數據框:

orange_ABC
orange_BCD
apple_ABC
apple_BCD
grape_ABC
grape_BCD

我需要rbind那些有他們的名字在普通(橘子,蘋果,葡萄)的第一部分,並命名新的數據幀這樣。 我正在從數據幀names(fruitlist)列表names(fruitlist) (從中制成上述數據幀)的列表中訪問名稱,並嘗試將lapplyfunction(x)配合使用而沒有運氣。 我對R有點陌生,所以在動態命名新數據框時,我想我犯了一個簡單的錯誤……

lapply(names(fruitlist),
       function(x){
         frame_nm <- toString((names(fruitlist[x])))
         frame_nm <- do.call(rbind, mget(ls(pattern=paste0((names(splitlist[x])),"*"))))
})

我已經在一種類型的“水果”上嘗試了獨立生產線,但似乎行得通:

test_DF <- do.call(rbind, mget(ls(pattern="apple*")))

編輯:我意識到我忘了提到動態創建6個數據幀的示例列表,所以我不能簡單地生成它們的列表。 但是,我確實有一個“水果”列表,並且所有新數據幀名稱的所有可能結尾都是已知的(“ _ABC”和“ _BCD”)。

如果您的fruitlist清單是數據幀的命名清單,則可能適合。

首先,將類似的名稱放入自己的列表中:

fruit.groups <- split(names(fruitlist), 
                      sapply(strsplit(names(fruitlist), split = "_"), "[[", 1))

> fruit.groups
$apple
[1] "apple_ABC" "apple_BCD"

$grape
[1] "grape_ABC" "grape_BCD"

$orange
[1] "orange_ABC" "orange_BCD"

然后,使用lapplyrbind按組:

fdf <- lapply(fruit.groups, function(x){
  out <- do.call(rbind, fruitlist[x])
  out$from <- gsub("(\\..*)", "", rownames(out))
  rownames(out) <- NULL
  return(out)
})

> fdf$apple
  a  b      from
1 1 11 apple_ABC
2 2 12 apple_ABC
3 3 13 apple_ABC
4 4 14 apple_ABC
5 1 11 apple_BCD
6 2 12 apple_BCD
7 3 13 apple_BCD
8 4 14 apple_BCD

偽數據:

namelist <- paste(fruit = rep(c("orange", "apple", "grape"), 2), 
                  nums =  rep(c("_ABC", "_BCD"), each =  3), sep = "")

fruitlist <- llply(namelist, function(x){
  assign(as.character(x), data.frame(a = 1:4, b = 11:14))
})

編輯:

從上述修改到您的問題:

如果您有成果和后綴,請使用expand.grid獲取所有可能的組合(假設所有組合都將引用動態生成的數據幀)。

fruits <- c("orange", "apple", "grape")
suffixes <- c("_ABC", "_BCD")
fullnames <- apply(expand.grid(fruits, suffixes), 1, paste, collapse = "")

使用該名稱列表,使用mget生成當前數據幀的列表。

new_fruit_df_list <- mget(fullnames)

然后,上面的代碼應該起作用,在此處進行修改以反映名稱更改:

fruit.groups <- split(names(new_fruit_df_list),
                      sapply(strsplit(names(new_fruit_df_list), split = "_"), "[[", 1))

fdf <- lapply(fruit.groups, function(x){
  out <- do.call(rbind, new_fruit_df_list[x])
  out$from <- gsub("(\\..*)", "", rownames(out))
  rownames(out) <- NULL
  return(out)
})

看看每列的開頭,添加的列(如果不需要的話刪除)顯示該行的原始數據框的名稱。

> lapply(fdf, head, 2)
$apple
  a  b      from
1 1 11 apple_ABC
2 2 12 apple_ABC

$grape
  a  b      from
1 1 11 grape_ABC
2 2 12 grape_ABC

$orange
  a  b       from
1 1 11 orange_ABC
2 2 12 orange_ABC

令人懷疑的是,為對象分配值的建議方法不起作用。 此外,在使用ls()mget()來列出和訪問函數中的命名對象時,必須mget()小心,因為除非它們另有說明,否則它們不會自動升至父級環境並且僅在本地范圍內“查看”變量。 這適用於R版本3.4,舊版本的行為可能有所不同。

  1. 創建命名對象。

    為了在全局環境中創建新對象,請使用assign() (已在盧克C的答案中建議):

     > assign("foo", "some text") > foo [1] "some text" 

    將代碼放在函數內部會引起局部作用域。 明確指定全局環境允許設置全局變量:

     > set_foo <- function (x) { assign("foo", x, envir=globalenv()) } > set_foo("other text") > foo [1] "other text" 

    請注意,省略envir參數將使全局環境不受影響。

  2. 在局部函數中使用ls() / mget()

    默認情況下,它僅列出該函數的當前(本地)環境中的名稱,該名稱僅在問題中給出的示例代碼中看到參數x 與上述類似,一種快速解決方案是通過添加參數envir=globalenv()顯式指定全局環境。 同樣適用於mget()

由於未提供MWE,因此我願意修改Luke C的答案中提供的“偽數據”示例代碼。

# Populate environment
namelist <- paste(fruit = rep(c("orange", "apple", "grape"), 2), 
                  nums =  rep(c("_ABC", "_BCD"), each =  3), sep = "")
for(x in namelist)
  assign(x, data.frame(a = 1:4, b = 11:14))

# The following re-generates the list of fruits used above
grouplist <- unique(unlist(lapply(strsplit(namelist, "_"), function (x) { x[[1]] })))
# Group and rbind by prefix, suppressing output
invisible(lapply(grouplist,
       function(x) {
         grouped <- do.call(rbind,
           mget(ls(pattern=paste0(x,"_*"), envir=globalenv()),
             envir=globalenv()))
         assign(x, grouped, envir=globalenv())
}))

試試看:

file_groups <- ls()[grep(".*_.*", ls())]
file_groups <- gsub("(.*)_.*", "\\1", file_groups)
df_list <- lapply(file_groups, 
                  function(x){ do.call(rbind, mget(ls(pattern = paste0(x, "*"))))})

暫無
暫無

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

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