[英]deparse(substitute()) with lapply
我想使用小型 function 和 lapply() 的組合為數據幀提供標簽
我有以下代碼:
df1 <- data.frame(c(1,2,3), c(3,4,5))
df2 <- data.frame(c(6,7,8), c(9,10,11))
f.generate.name <- function(x) {
x$name <- deparse(substitute(x))
return(x)
}
my_list <- list(df1, df2)
# This works fine.
f.generate.name(df1)
# This does not work.
lapply(my_list, f.generate.name)
產生以下 output
[[1]]
c.1..2..3. c.3..4..5. name
1 1 3 X[[i]]
2 2 4 X[[i]]
3 3 5 X[[i]]
[[2]]
c.6..7..8. c.9..10..11. name
1 6 9 X[[i]]
2 7 10 X[[i]]
3 8 11 X[[i]]
我想要的是:
[[1]]
c.1..2..3. c.3..4..5. name
1 1 3 df1
2 2 4 df1
3 3 5 df1
[[2]]
c.6..7..8. c.9..10..11. name
1 6 9 df2
2 7 10 df2
3 8 11 df2
不使用循環的最佳方法是什么? 我如何調整我創建的 lapply() function 或 function 以獲得所需的結果?
lapply()
不能迭代多個參數。 在這種情況下,您可以使用mapply()
或其包裝器Map()
始終返回一個列表。
Map(f = function(x, y){
x$name <- y
x },
my_list,
names(my_list))
$df1
c.1..2..3. c.3..4..5. name
1 1 3 df1
2 2 4 df1
3 3 5 df1
$df2
c.6..7..8. c.9..10..11. name
1 6 9 df2
2 7 10 df2
3 8 11 df2
如果您願意接受purrr
解決方案,您可以使用imap()
。 它使 object 的名稱方便地獲得。 則無需編寫 function :
my_list <- list(df1 = df1, df2 = df2)
imap(my_list, ~{
.x$name <- .y
.x
})
$df1
c.1..2..3. c.3..4..5. name
1 1 3 df1
2 2 4 df1
3 3 5 df1
$df2
c.6..7..8. c.9..10..11. name
1 6 9 df2
2 7 10 df2
3 8 11 df2
真正的問題是這些名字是從哪里來的? 像問題中的my_list
這樣的未命名列表丟失了df1
和df2
名稱,我們可以通過查看其內部結構看到:
dput(my_list) # no df1 or df2 seen
## list(structure(list(c.1..2..3. = c(1, 2, 3), c.3..4..5. = c(3,
## 4, 5)), class = "data.frame", row.names = c(NA, -3L)), structure(list(
## c.6..7..8. = c(6, 7, 8), c.9..10..11. = c(9, 10, 11)), class =
## "data.frame", row.names = c(NA,
## -3L)))
因此,要么我們首先需要創建一個命名列表,要么提供一個名稱向量。 我們僅使用基礎 R 來展示兩者。
首先創建數據幀的命名列表,然后使用 Map,如下所示:
L <- mget(ls("^df")) # create named list
Map(data.frame, L, name = names(L))
或者,如果您只有一個未命名的列表,那么我們可以 Map 和名稱向量:
my_list <- list(df1, df2) # unnamed list as in question
Map(data.frame, my_list, name = c("df1", "df2"))
另一種方法是傳遞單個數據幀而不是列表。 因為我們沒有通過創建未命名列表來破壞原始名稱,所以我們仍然可以檢索它們。 在 R 4.0 和更高版本上,可以選擇使用deparse1
代替代碼中的deparse
。
add_names <- function(...) {
mc <- match.call()
Map(data.frame, list(...), names = sapply(mc[-1], deparse))
}
add_names(df1, df2)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.