【问题标题】:A operator to system() in RR中system()的运算符
【发布时间】:2012-08-12 21:58:51
【问题描述】:

我想让 R 更容易执行系统命令。像 ipython 与 python 之类的东西。以下是一些想法:

  • 定义 cd 函数以通过包装 getwd 和 setwd 来更改工作目录
  • 定义一个运算符来包装 system() 命令,这样我就可以运行类似 "$ls" 的东西来替换 system("ls")

第一个很容易完成。但是,我坚持使用第二个。我发现没有办法在 R 中为字符串重新定义运算符。然后我退后一步,我尝试定义一个 sys(param)。但是现在,我仍然需要输入引号。例如我需要运行 sys("ls") 而不是 sys(ls) 来列出目录。有没有办法让参数假设它是一个字符串,即使没有引号?谢谢。欢迎提出任何建议。

【问题讨论】:

  • @Bob,你的意思是这样吗? stackoverflow.com/questions/520810/…
  • 如果您的意思是希望能够将foo 作为函数/命令而不是foo() 键入,那么请查看makeActiveBinding。这是我在我的 Rprofile 中加载的一个:invisible(makeActiveBinding('prev', function(...) .Last.value, .GlobalEnv))。如果您希望能够加载完整的命令字符串,可能 GSee 的链接是要走的路。
  • @CarlWitthoft,你为什么把它包装在invisible中?我的 .Rprofile 中有一个几乎相同的功能:makeActiveBinding("ans", function().Last.value, .GlobalEnv)
  • 非常感谢 cmets:@Dason:dir() 绝对比 system("ls") 好,我没有注意到。但是这里的“ls”只是一个例子。我每天都在使用大量的常用命令,例如 system("rm foo")、system("mv foo foo1")、system("cp foo foo1"),如果我能做得更快,我将不胜感激。 @GSee:该链接确实有很大帮助,我想我可以从那里开始工作。 @CarlWitthoft:makeActiveBinding 很明确,我非常喜欢它。但是您是否知道类似的事情以便我可以将参数传递给它?我的意思是这样我就可以运行类似 sys ls 而不是 sys(ls) 的东西。
  • 您的最后一个请求是要求将 空格 重新定义为函数式操作。我认为在 R 语法的上下文中这是相当不明智的。您的第一个请求似乎是扩展“$”的定义。这似乎可以说是明智的。

标签: r


【解决方案1】:

更新以简化功能(删除正则表达式)并添加对字符输入的支持

您可以在函数内使用match.call,这样您就可以在不使用引号的情况下调用该函数。

sys <- function(...) {
  command <- match.call()[[2L]]
  if (!is.character(command)) {
    command <- gsub("- ", "-", deparse(command))
  }
  system(command)
}

现在,以下任何一个都等效于system("ls -a")

sys("ls -a")
sys(ls -a)

上面的sys 函数提取了调用的第二个组成部分,即括号之间的内容。即这些示例中的ls -a 或"ls -a"。然后将其传递给system(如果不是character,则首先通过deparse)

[我添加了对字符串的支持,否则它不适用于正斜杠、点等。例如,sys(ls /home) 不起作用,但 sys("ls /home") 起作用。]

但是,这仍然需要使用括号 :-(


为避免使用括号,您可以屏蔽运算符。在这个答案的初始版本中,我展示了如何屏蔽!,这不是一个好主意。您建议在 cmets 中使用 ?,可以这样做。

`?` <- function(...) {
  command <- match.call()[[2L]]
  if (!is.character(command)) {
    command <- gsub("- ", "-", deparse(command))
  }
  system(command)
} 

现在,这与system("ls -a -l") 相同

?ls -a -l

但是,如果您需要使用正斜杠,则必须使用这样的引号

?"ls /home"

或者,您可以创建一个特殊的二元运算符

"%sys%" <- function(...) {
  system(sub("%sys%", "", deparse(match.call())))
}

你可以这样使用它

ls %sys% -l
ls %sys% .

如果需要使用正斜杠,则必须在右侧引用

ls %sys% "/home"

一个缺点是它只需要在运算符右侧有一个参数。

【讨论】:

  • 不过从头开始就好了。
  • 你救了我。谢谢。我不认为要更换!也是个好主意。它可能会弄乱很多功能。
  • 诅咒。我想我只是无法回到那种打孔卡宏的思维模式。我想我陷入了功能性思维的陈规之中。
  • 您可以使用littler(或 Rscript)从控制台运行 R 命令,而不是从 R 中运行控制台命令
  • @Bob 你也不应该这样做,因为??? 是非常有用的包sos 的sekit codezz。
猜你喜欢
  • 2018-11-10
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 2019-09-06
  • 2017-09-10
相关资源
最近更新 更多