gpt4 book ai didi

r - 访问作为 apply 内参数传递的变量名称

转载 作者:行者123 更新时间:2023-12-02 01:23:50 25 4
gpt4 key购买 nike

我在另一篇文章中提出了几乎相同的问题,但只询问列名称,并收到了满足该需求的完美解决方案。现在我需要的是变量全名。我在这里重新表述。

我在函数内部使用“deparse(substitute(x))”来获取作为参数传递的变量名称。它效果很好......但不适用于“lapply”

myfun <- function(x)
{
return(deparse(substitute(x)))
}

a <- c(1,2,3)
b <- c(4,5,5)
df<-data.frame(a,b)
myfun(df$a)

[1] "df$a"

但是,用“lapply”...

lapply(df, myfun)
$a
[1] "X[[i]]"

$b
[1] "X[[i]]"

如何获取“lapply”内的变量名称?

谢谢

最佳答案

当您将数据帧传递给lapply时,它会使用双方括号通过数字索引(而不是名称索引)来迭代列使用 $ 访问器。它相当于使用以下循环:

X <- df
result <- list()

for(i in seq_along(X)) {
result[[i]] <- myfun(X[[i]])
}

names(result) <- names(X)

result
#> $a
#> [1] "X[[i]]"
#>
#> $b
#> [1] "X[[i]]"

因此,简单的 deparse(substitute(x))lapply 中不起作用。您不是恢复列名称,而是需要从调用堆栈重建它。这充满了警告和陷阱,但(相对)简单的方法是:

myfun <- function(x) {
stack <- lapply(sys.calls(), function(x) sapply(as.list(x), deparse))

if(stack[[length(stack)]][1] == 'myfun') {
return(stack[[length(stack)]][2])
}

if(stack[[length(stack)]][1] == 'FUN') {
return(paste0(stack[[length(stack) - 1]][2], '$',
eval(quote(names(X)[i]), parent.frame())))
}

deparse(substitute(x))
}

这意味着如果直接调用,您的函数仍然可以工作:

myfun(df$a)
#> [1] "df$a"

但也适用于lapply

lapply(df, myfun)
#> $a
#> [1] "df$a"
#>
#> $b
#> [1] "df$b"

lapply(iris, myfun)
#> $Sepal.Length
#> [1] "iris$Sepal.Length"
#>
#> $Sepal.Width
#> [1] "iris$Sepal.Width"
#>
#> $Petal.Length
#> [1] "iris$Petal.Length"
#>
#> $Petal.Width
#> [1] "iris$Petal.Width"
#>
#> $Species
#> [1] "iris$Species"

它是专门为涵盖直接使用或在lapply内使用而编写的。如果您想扩展其用途以在其他函数调用中工作,例如 Map 或各种 purrr 映射函数,那么这些函数必须由它们自己的 专门覆盖if 子句。

关于r - 访问作为 apply 内参数传递的变量名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75396743/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com