将元素附加到列表只有在它们存在的情况下。

huangapple go评论139阅读模式
英文:

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) {

  1. # Get new element
  2. # 获取新元素
  3. if (exists(element_name)) {
  4. element &lt;- list(get(element_name))
  5. names(element) &lt;- element_name
  6. } else {
  7. element &lt;- list(NA)
  8. names(element) &lt;- element_name
  9. }
  10. # Append new element
  11. # 附加新元素
  12. my_list &lt;- 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:

  1. genes &lt;- c(&quot;gene1&quot;, &quot;gene2&quot;, &quot;gene3&quot;, &quot;gene4&quot;)
  2. analyses &lt;- c(&quot;analysis_one&quot;, &quot;analysis_two&quot;)
  3. # Function to put together a list even if an element doesn&#39;t exist
  4. append_if_exists &lt;- function(element_names) {
  5. # Create empty list
  6. my_list &lt;- list()
  7. # Get and append each new element
  8. for (element_name in element_names) {
  9. # Get new element
  10. if (exists(element_name)) {
  11. element &lt;- list(get(element_name))
  12. names(element) &lt;- element_name
  13. } else {
  14. element &lt;- list(NA)
  15. names(element) &lt;- element_name
  16. }
  17. # Append new element
  18. my_list &lt;- c(my_list, element)
  19. }
  20. # Output
  21. return(my_list)
  22. }
  23. my_function &lt;- function(genes, analyses) {
  24. # Analysis one
  25. if (&quot;analysis_one&quot; %in% analyses) {
  26. output1 &lt;- genes[1:3]
  27. }
  28. # Analysis two
  29. if (&quot;analysis_two&quot; %in% analyses) {
  30. output2 &lt;- genes[1:2]
  31. }
  32. # Append if exists
  33. out &lt;- append_if_exists(c(&quot;output1&quot;, &quot;output2&quot;))
  34. return(out)
  35. }
  36. # Run the function and my list has the right names, but the elements are just &#39;NA&#39;
  37. result &lt;- my_function(genes, analyses)
  38. # Run the same thing outside of the function and it works fine!
  39. output1 &lt;- genes[1:3]
  40. output2 &lt;- genes[1:2]
  41. result &lt;- append_if_exists(c(&quot;output1&quot;, &quot;output2&quot;))

答案1

得分: 1

不需要回答我要翻译的问题。以下是翻译的内容:

与编写自己的append_if_exists不同,只需使用内置的mget()函数。如果要避免不存在的名称,可以将名称与当前范围中的名称相交。这应该可以工作。

问题在于您的解决方案需要注意对象被找到的环境。R使用词法作用域,因此函数在定义函数的环境中解析变量,而不是在调用函数的环境中。如果您在全局环境中定义了append_if_exists,那么它无法看到在my_function运行时环境中定义的output1output2get()函数确实有一个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

  1. my_function &lt;- function(genes, analyses) {
  2. ...
  3. out &lt;- mget(intersect(c(&quot;output1&quot;, &quot;output2&quot;), ls()))
  4. return(out)
  5. }

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.

huangapple
  • 本文由 发表于 2023年8月5日 04:46:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76839028.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定