英文:
Function to append elements to a list only if they exist
问题
I've created this function that puts together a list from object names, but can handle when the object doesn't exist. The function works fine on its own, but when I try and call it within another function I just get NA
out for each list element. What's going on? Here's a simplified example:
我创建了这个函数,它可以从对象名称组合列表,但可以处理对象不存在的情况。这个函数单独运行正常,但当我尝试在另一个函数中调用它时,每个列表元素都变成了NA
。发生了什么?以下是一个简化的示例:
genes <- c("gene1", "gene2", "gene3", "gene4")
analyses <- c("analysis_one", "analysis_two")
Function to put together a list even if an element doesn't exist
用于组合列表的函数,即使元素不存在也可以处理
append_if_exists <- function(element_names) {
Create empty list
创建一个空列表
my_list <- list()
Get and append each new element
获取并附加每个新元素
for (element_name in element_names) {
# Get new element
# 获取新元素
if (exists(element_name)) {
element <- list(get(element_name))
names(element) <- element_name
} else {
element <- list(NA)
names(element) <- element_name
}
# Append new element
# 附加新元素
my_list <- c(my_list, element)
}
Output
输出
return(my_list)
}
my_function <- function(genes, analyses) {
Analysis one
分析一
if ("analysis_one" %in% analyses) {
output1 <- genes[1:3]
}
Analysis two
分析二
if ("analysis_two" %in% analyses) {
output2 <- genes[1:2]
}
Append if exists
如果存在则附加
out <- append_if_exists(c("output1", "output2"))
return(out)
}
Run the function and my list has the right names, but the elements are just 'NA'
运行函数,我的列表有正确的名称,但元素只是'NA'
result <- my_function(genes, analyses)
Run the same thing outside of the function and it works fine!
在函数外运行相同的内容,它正常工作!
output1 <- genes[1:3]
output2 <- genes[1:2]
result <- append_if_exists(c("output1", "output2"))
英文:
I've created this function that puts together a list from object names, but can handle when the object doesn't exist. The function works fine on its own, but when I try and call it within another function I just get NA
out for each list element. What's going on? Here's a simplified example:
genes <- c("gene1", "gene2", "gene3", "gene4")
analyses <- c("analysis_one", "analysis_two")
# Function to put together a list even if an element doesn't exist
append_if_exists <- function(element_names) {
# Create empty list
my_list <- list()
# Get and append each new element
for (element_name in element_names) {
# Get new element
if (exists(element_name)) {
element <- list(get(element_name))
names(element) <- element_name
} else {
element <- list(NA)
names(element) <- element_name
}
# Append new element
my_list <- c(my_list, element)
}
# Output
return(my_list)
}
my_function <- function(genes, analyses) {
# Analysis one
if ("analysis_one" %in% analyses) {
output1 <- genes[1:3]
}
# Analysis two
if ("analysis_two" %in% analyses) {
output2 <- genes[1:2]
}
# Append if exists
out <- append_if_exists(c("output1", "output2"))
return(out)
}
# Run the function and my list has the right names, but the elements are just 'NA'
result <- my_function(genes, analyses)
# Run the same thing outside of the function and it works fine!
output1 <- genes[1:3]
output2 <- genes[1:2]
result <- append_if_exists(c("output1", "output2"))
答案1
得分: 1
不需要回答我要翻译的问题。以下是翻译的内容:
与编写自己的append_if_exists
不同,只需使用内置的mget()
函数。如果要避免不存在的名称,可以将名称与当前范围中的名称相交。这应该可以工作。
问题在于您的解决方案需要注意对象被找到的环境。R使用词法作用域,因此函数在定义函数的环境中解析变量,而不是在调用函数的环境中。如果您在全局环境中定义了append_if_exists
,那么它无法看到在my_function
运行时环境中定义的output1
和output2
。get()
函数确实有一个envir=
参数,所以您可以将适当的环境传递给该函数,但这可能会很快变得混乱。
英文:
Rather than write your own append_if_exists
, just use the built in mget()
function. If you want to avoid names that don't exist, intersect the names with the names in the current scope. This should work
my_function <- function(genes, analyses) {
...
out <- mget(intersect(c("output1", "output2"), ls()))
return(out)
}
The problem with your solution is that you need to pay attention to the environment where objects are found. R uses lexical scoping, so functions resolve variables in the environment where the function was defined, not where it was called. If you define append_if_exists
in the global environment, then it can't see output1
and output2
which are defined in the my_function
runtime environment. The get()
function does have an envir=
parameter so you could pass in the appropriate environment to the function but that would get messy quickly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论