【问题标题】:R - How to extract values for the same named elements across multiple objects of the same type?R - 如何跨相同类型的多个对象提取相同命名元素的值?
【发布时间】:2012-09-25 17:44:34
【问题描述】:

我的工作区中有一系列对象存储一些统计模型的结果。称它们为“model1”、“model2”等。这些模型中的每一个都附加了相同的命名元素集,例如 $coef。我想从包含字符串“model”的所有对象中提取存储在特定元素中的值到一个列表或向量中。

在命令行输入的以下代码符合我的要求:

unlist(lapply(parse(text = paste0(ls()[grep("model", ls() )], "$", "coef")), eval))

由此,我创建了以下通用函数:

get.elements <- function(object, element) {
    unlist(lapply(parse(text = paste0(ls()[grep(object, ls() )], "$", element)), eval))
}

但是,当我运行此函数时,我收到以下错误:

Error in parse(text = paste0(ls()[grep(object, ls() )], "$", element)) : 
  <text>:1:1: unexpected '$'
1: $
   ^

第一季度。为什么这段代码在命令行运行时可以运行,而不是作为函数运行,更重要的是,我该如何修复它?

第二季度。更好的是,有没有更简单的方法可以完成同样的事情?对于统计学家和模拟建模师来说,这似乎是一项常见的任务,我希望基本包中有某种命令,但我一直找不到任何东西。肯定有比我繁琐的方法更优雅的方法来做到这一点。

感谢大家的帮助。

--戴夫

【问题讨论】:

  • 你用什么参数来调用函数?
  • 您可以使用代码m[["coefficients"]] 访问模型中的系数,因此您可以使用m[[element]]。此外,将多个模型保存为名为@9​​87654326@、model2 的变量是一个糟糕的选择:您应该将它们保存为模型列表。这样,你可以得到这样的系数:lapply(models, function(m) m[[element]])

标签: r


【解决方案1】:

Q1) 代码失败,因为ls() 在函数的环境中查找,并且那里没有匹配的对象,

paste0(ls()[grep(object, ls() )], "$", element)

等价于

paste0("$", element)

要让ls() 查看您的工作区,您需要ls(pos = 1)

Q2) 这是一项常见任务,但据了解,没有函数可以执行此操作,因为模型在哪里、它们被称为什么、要提取的对象以及返回的方式取决于模型根据您的要求。你上面建议的一个稍微整洁的版本是

nm <- paste0("model", 1:2) # adjust numbers as required
unlist(lapply(nm, function(x) get(nm)$coef))

或者,您可以将模型放在列表中并使用

modList <- list(model1, model2)
unlist(lapply(modList, "[[", "coefficients"))

【讨论】:

  • 我相信您可以通过调用sapply 来替换unlist(lapply()),即sapply(modList, "[[", "coefficients"))
  • @PaulHiemstra 在这种情况下,sapply 存在一个问题:如果第一个模型的系数名称与第二个模型的系数名称不同,则输出(其中只有使用第一个模型)可能会产生误导。当然,这仅在所有模型具有相同数量的系数时才有意义。如果系数的数量不同,sapply 的输出将与lapply 的输出相同。
  • @SvenHohenstein 点了,我认为使用unlist 更好。
  • 谢谢!有关环境以及 ls() 如何在函数内部工作的信息特别有用。
【解决方案2】:

您可以使用purrr package 中的地图。

l1 <- list(a1 = 3, a2 = 2)
l2 <- list(a1 = 334, a2 = 34)
l3 <- list(a1 = 90, a2 = 112)

l <- list(l1, l2, l3)

purrr::map(l, "a1")

这给出了:

### Result
[[1]]
[1] 3

[[2]]
[1] 334

[[3]]
[1] 90

【讨论】:

    【解决方案3】:

    这是获得所需输出的一种方式:

    get.elements <- function(object, element) {
     unlist(lapply(ls(pattern = object, .GlobalEnv),
            function(x) get(x, .GlobalEnv)[[element, exact = FALSE]]))
    }
    

    elementobject 都是字符串。

    请注意,我使用了参数exact = FALSE,因为元素名为coefficients,而不是coef。这样,你仍然可以使用element = "coef"

    【讨论】:

    • 这在使用列表和索引方面似乎相当麻烦,请参阅@HeatherTurner 的答案。
    • 同意,但这只有在对象已经在列表中时才有效。
    • 而 OP 应该做到这一点,IMO 并不难 :)
    • 人们似乎忘记了ls 有一个pattern 参数,而grep 有一个value 参数
    • +1 好主意@GSee! - 我更新了我的答案。感谢您指出这些技巧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 2021-10-09
    相关资源
    最近更新 更多