R 中使用 mapply 对子集参数进行非标准评估

2024-01-24

我无法使用subset的论证xtabs or aggregate(或我测试过的任何功能,包括ftable and lm) with mapply。以下调用失败并显示subset争论,但它们的工作没有:

mapply(FUN = xtabs,
       formula = list(~ wool,
                      ~ wool + tension),
       subset = list(breaks < 15,
                     breaks < 20),
       MoreArgs = list(data = warpbreaks))

# Error in mapply(FUN = xtabs, formula = list(~wool, ~wool + tension), subset = list(breaks <  : 
#   object 'breaks' not found
# 
# expected result 1/2:
# wool
# A B 
# 2 2
# 
# expected result 2/2:
#     tension
# wool L M H
#    A 0 4 3
#    B 2 2 5

mapply(FUN = aggregate,
       formula = list(breaks ~ wool,
                      breaks ~ wool + tension),
       subset = list(breaks < 15,
                     breaks < 20),
       MoreArgs = list(data = warpbreaks,
                       FUN = length))

# Error in mapply(FUN = aggregate, formula = list(breaks ~ wool, breaks ~  : 
#   object 'breaks' not found
# 
# expected result 1/2:
#   wool breaks
# 1    A      2
# 2    B      2
# 
# expected result 2/2:
#   wool tension breaks
# 1    B       L      2
# 2    A       M      4
# 3    B       M      2
# 4    A       H      3
# 5    B       H      5

这些错误似乎是由于subset未在正确的环境中评估参数。我知道我可以在data与争论data = warpbreaks[warpbreaks$breaks < 20, ]作为一种解决方法,但我希望提高我对 R 的了解。

我的问题是:

  • 我该如何使用subset争论与mapply?我尝试过match.call and eval.parent,但到目前为止还没有成功(更多细节在我的之前的问题 https://stackoverflow.com/a/55828617/11148823).
  • 为什么是formula参数评估于data = warpbreaks, 但 这subset说法不是吗?

简而言之,当您创建一个列表作为参数传递给函数时,它会在创建时进行评估。您收到的错误是因为 R 尝试创建您想要在调用环境中传递的列表。

为了更清楚地看到这一点,假设您尝试在调用之前创建要传递的参数mapply:

f_list <- list(~ wool, ~ wool + tension)
d_list <- list(data = warpbreaks)
mapply(FUN = xtabs, formula = f_list, MoreArgs = d_list)
#> [[1]]
#> wool
#>  A  B 
#> 27 27 
#> 
#> [[2]]
#>     tension
#> wool L M H
#>    A 9 9 9
#>    B 9 9 9

创建公式列表没有问题,因为这些公式在需要时才会被评估,当然warpbreaks可以从全局环境访问,因此调用mapply works.

当然,如果您尝试在之前创建以下列表mapply call:

subset_list <- list(breaks < 15, breaks < 20)

然后R会告诉你breaks没有找到。

但是,如果您使用以下命令创建列表warpbreaks在搜索路径中,那么你就不会有问题:

subset_list <- with(warpbreaks, list(breaks < 15, breaks < 20))
subset_list
#> [[1]]
#>  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [14]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
#> [27] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [40] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
#> [53] FALSE FALSE
#> 
#> [[2]]
#>  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
#> [14]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE
#> [27] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
#> [40]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
#> [53]  TRUE FALSE

所以你会认为我们可以把它传递给mapply一切都会好起来的,但现在我们收到一个新错误:

mapply(FUN = xtabs, formula = f_list, subset = subset_list, MoreArgs = d_list)
#> Error in eval(substitute(subset), data, env) : object 'dots' not found

那我们为什么会得到这个呢?

问题在于传递给的任何函数mapply那个电话eval,或者它们本身调用一个使用的函数eval.

如果你查看源代码mapply你会看到它需要你传递的额外参数并将它们放入一个名为的列表中dots,然后它将传递给内部mapply call:

mapply
#> function (FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE) 
#> {
#>     FUN <- match.fun(FUN)
#>     dots <- list(...)
#>     answer <- .Internal(mapply(FUN, dots, MoreArgs))
#> ...

If your FUN它本身调用另一个函数,该函数调用eval因此,对于其任何论点,它将尝试eval物体dots,它不会存在于其中的环境中eval叫做。通过执行以下操作很容易看到这一点mapply on a match.call包装:

mapply(function(x) match.call(), x = list(1))
[[1]]
(function(x) match.call())(x = dots[[1L]][[1L]])

所以我们的错误的最小可重现示例是

mapply(function(x) eval(substitute(x)), x = list(1))
#> Error in eval(substitute(x)) : object 'dots' not found

那么解决办法是什么呢?看来您已经找到了一个非常好的方法,即手动对您希望传递的数据帧进行子集化。其他人可能会建议您探索purrr::map以获得更优雅的解决方案。

然而,它is可能得到mapply做你想做的事,秘诀就是修改FUN将其变成匿名包装xtabs动态子集:

mapply(FUN = function(formula, subset, data) xtabs(formula, data[subset,]), 
       formula = list(~ wool, ~ wool + tension),
       subset = with(warpbreaks, list(breaks < 15, breaks < 20)),
       MoreArgs = list(data = warpbreaks))
#> [[1]]
#> wool
#> A B 
#> 2 2 
#> 
#> [[2]]
#>     tension
#> wool L M H
#>    A 0 4 3
#>    B 2 2 5
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R 中使用 mapply 对子集参数进行非标准评估 的相关文章

  • 用整数矩阵对 data.frame 进行子集化

    我一直遇到这个问题 想知道是否有一个简单的解决方法 对于某些情况 我发现考虑将矩阵子集化更合乎逻辑 N lt 12 N NA lt 6 dat lt data frame V1 runif N V2 runif N sel mat lt m
  • 使填充的值成为ggplot2中的实际填充

    有没有办法让填充的值 标签 成为填充本身 例如 在堆积条形图中 我有 require ggplot2 big votes movies movies movies votes gt 100000 p ggplot big votes mov
  • 如何避免循环

    大家好 我是 R 新手 我有两个面板数据文件 其中包含 id date 和 ret 列 文件 A 的数据比文件 B 多得多 但我主要处理文件 B 数据 id 和 date 的组合是唯一标识符 有没有一种优雅的方式来查找 B 中的每个 id
  • 无法使用include_graphics在Rmarkdown中插入png(错误:文件不是PNG格式)

    这个错误很奇怪 当我编织文档时 出现以下错误 Quitting from lines 42 43 sigminer doc Rmd Error in png readPNG path native TRUE info TRUE file i
  • 在开发模式下安装包(R源未编译成Rdb)

    我需要修改R代码在一个R具有 Fortran 绑定的包 当我安装软件包时 我看到存储库目录没有源代码 但是 Rdb而是二进制文件 我看了看devtools包 但我仍然不清楚如何在不编译 R 源部分的情况下安装该包 类似于 python py
  • 在绘图中的所有坐标之间绘制线条

    我有以下数据框 data lt data frame x c 5 1 3 2 5 7 12 y c 5 7 6 1 3 5 6 我可以使用 ggplot 函数绘制这些坐标 并在这些坐标之间画一条线 ggplot data aes x y g
  • PCA 图中带有名称的工具提示

    我想用 ggplotly 生成交互式绘图 工具提示应该显示变量的名称 interactive lt ggplotly pca dynamicTicks T tooltip c x y label list pca 是 PCA 的可视化 su
  • 如何找到每个分类变量的连续变量的平均值

    我想在 y 轴上绘制连续的 BMI 在 x 轴上绘制家庭收入的分类变量 并且我希望该图绘制每个类别的平均 BMI 然而 我不知道如何找到家庭收入每个因素的平均体重指数 Dataset nh 5994 total IDs with Obser
  • 如何将美国人口普查局的州级形状文件合并为全国性形状

    人口普查局不提供全国范围内公共使用微数据区域的形状文件 美国社区调查中可用的最小地理区域 我尝试用几种不同的方法将它们结合起来 但即使是消除重复标识符的方法一旦到达加利福尼亚州也会崩溃 我是在做一些愚蠢的事情还是需要一个困难的解决方法 下面
  • 如何在 R 中执行随机森林/交叉验证

    我无法找到对我尝试生成的回归随机森林模型执行交叉验证的方法 因此 我有一个数据集 其中包含 1664 个解释变量 不同的化学性质 和一个响应变量 保留时间 我正在尝试生成一个回归随机森林模型 以便能够预测给定保留时间的物质的化学性质 ID
  • 从 foreach 循环赋值

    我想并行化一个循环 例如 td lt data frame cbind c rep 1 4 2 rep 1 5 rep 1 10 2 names td lt c val id res lt rep NA NROW td for i in l
  • 将值添加到 rCharts hPlot 工具提示

    我想通过 rCharts 向标准 Highcharts 工具提示添加一些额外的值 示例代码 require rCharts df lt data frame x c 1 5 y c 5 1 z c A B C D E name c K L
  • 当按多列分组时,如何命名 dplyr 中的 group_split 列表

    我在 dplyr 中使用 group split 在分割了多个列后 我很难命名列表 当我们按一列分组时 我知道该怎么做here https stackoverflow com questions 57107721 how to name t
  • R 中有没有快速替换列值的方法?

    假设我们有一个包含数值的数据框 如下所示 Temperature Height 32 157 31 159 33 139 我想更换Height价值观与pic 00001 pic 00002等等 最终结果是 Temperature Heigh
  • 使用facet时ggplot2控制每行的面板数量?

    Is it possible to control the number of panels per row in a ggplot I can only get an equal number of panels on each row
  • 使用 Rcpp 得出斐波那契数列的意外结果

    我刚刚开始使用Rcpp很抱歉 如果我错过了一个简单的步骤或类似的东西 我已经尝试过这个 sourceCpp library Rcpp sourceCpp code include
  • 在R中绘制3x3方形网格

    我得到了一个数字列表 n 9 想将它们画在一个 3 3 的正方形网格中 每个网格填充相应的数字 我如何在 R 中执行此操作而不安装额外的软件包 例如情节 非常感谢 这里有一个ggplot解决方案比我预期的要难一点 Setup the dat
  • 如何从类外部更改公共 R6 类方法?

    我希望能够在我的 R6 类中重新定义公共方法 以便它根据该类保存的数据类型进行更改 如下所示 library R6 Simple lt R6Class Simple public list dt mtcars my print functi
  • 如何获取调用函数的“this”值?

    如果我有一个这样的函数 function foo this console log this function bar bar prototype func function foo this var test new bar test f
  • (R 错误)错误:cons 内存耗尽(达到限制?)

    我正在处理大数据 并且有一个 70GB 的 JSON 文件 我正在使用 jsonlite 库将文件加载到内存中 我尝试过 AWS EC2 x1 16large 机器 976 GB RAM 来执行此负载 但 R 因错误而中断 Error co

随机推荐