【发布时间】:2020-10-13 23:09:48
【问题描述】:
一年多来,我一直在努力寻找解决方案,并决定写一篇关于它的帖子。任何帮助,将不胜感激。这是我可以在 Stata 和 SAS 中轻松完成但我不知道如何在 R 中完成的伪代码。{} 是今年引入 dplyr 的类似胶水的运算符, 所以我将它用作使伪代码工作的运算符的占位符。
library(tidyverse)
var <- "mpg"
df_name <- "mtcars"
{df_name} %>% count({var})
{df_name}_1 <- {df_name} %>% mutate(., {var}_1={var}/2)
length({df_name}_1)
应该导致
library(tidyverse)
var <- "mpg"
df_name <- "mtcars"
mtcars %>% count(mpg)
mtcars_1 <- mtcars %>% mutate(., mpg_1=mpg/2)
length(mtcars_1)
在 Stata 中,我可以轻松地使用这样的本地或全局宏:
local df_name "mtcars"
然后将其引用为 `df_name'
在 SAS 中,我可以使用这样的全局宏:
%LET df_name=mtcars;
然后像 &df_name 一样引用它。
请注意引用这些值在视觉上是多么容易——没有赋值、获取、括号、mgets等。
这两种方法都允许在数据集名称、函数、变量等中使用它们。极大地简化了我的代码并为我节省了大量时间。如何在 R 中使用视觉简洁性来做到这一点?我的代码对于熟悉 Stata/SAS 的人来说应该是可读的(dplyr 在这方面很棒!),太多的 eval,将所有东西包装在函数中,用括号赋值只会让他们放弃项目或迫使我改回SAS/Stata。
我尝试了 {{}}、!!、enquo、sym 和 NSE 的所有组合,但仍然不知道如何以一种视觉上简单的方式使其工作。在 dplyr 管道中,变量名终于有了一些解决方法,但数据帧和基础 R 没有。
我非常感谢您在这件事上的任何帮助!我在 2009 年使用 R 时遇到了这个问题,并放弃了 R,直到我不得不在 2019 年回来,但仍然找不到解决这个问题的简单方法。
【问题讨论】:
-
df_name是否需要存储文本变量?如果您想以类似 SAS 的方式将其保存在一个简单的脚本中,为什么不将数据集的名称分配给该对象呢?df_name <- mtcars那么你可以做df_name %>% count(!!var)或length(df_name[[var]])吗? -
我认为 R 中没有类似的东西(尽管也许有人会展示一些做得很好的包)。我不认为你会喜欢这个,但基本上每当你想这样做时,我认为你应该使用函数。这本质上就是函数参数的工作方式。当我有
foo <- rnorm(16)并且我有mean(foo)时,mean函数在内部将foo引用为x。当我执行lm(mpg ~ hp, data = mtcars)时,lm函数仅在内部使用data,名称或参数。 R 是一种函数式语言,R 实现这些目的的方式是通过函数。 -
是的,将所有内容都封装在函数中会使所有内容都很难使用和调试。这都是学术研究,不是生产就绪的东西。
-
尊敬的,这是一种范式转变。生产代码不使用函数来使事情难以使用和调试。生产代码使用函数(最好是许多小函数,而不是一个大函数),因为它更容易测试、调试和使用。举个例子,你正在为此苦苦挣扎,但如果你使用函数,这不是问题。如果你从滑雪转向单板滑雪,你也必须在某个时候放开杆子。
-
@thelatemail 在 SAS 中,每个 DATA STEP 都可以生成一个 &df_name._1 新文件,这样前一个文件和新文件就存在并且可以进行比较、调试等等。我如何使用您的方法执行 {df_name}_1 % mutate(., {var}_1={var}/2) ?我实际上不想在环境中只有 mtcars_* 的 df_name 命名数据框。感谢您的答复!我需要绝对确定它不能完成。
标签: r dataframe dplyr tidyverse nse