【问题标题】:Code refactoring: from $ to [[代码重构:从 $ 到 [[
【发布时间】:2016-10-20 10:04:44
【问题描述】:

我有很多使用$ 运算符而不是[[ 的代码。我已经阅读了[[ 的许多优点,并想重构所有代码。

下面的方法会不会有问题?我怎样才能最好地在 Mac 上使用 RStudio 或 TextWrangler 进行搜索和替换?

l <- list()
l$`__a` <- data.frame(`__ID` = stringi::stri_rand_strings(10, 1), col = stringi::stri_rand_strings(10, 1), check.names = F )

现在的代码如下所示:

l$`__a`$`__ID`

我想将其重构为:

l[["__a"]][["__ID"]]

要实现这一点,以下替换是否足够?

$` to [["

` to "]]

我在我的代码中发现了此方法不起作用的一个区域,现在我还找到了一种解决方法来避免该问题:Avoiding backtick characters with dplyr

df <- dat[["__Table"]] %>% select(`__ID` ) %>% mutate(fk_table = "__Table", val = 1)

在进行上述替换之前,我需要将 select 函数更改为此,以避免对反引号字符进行错误替换:

select_(as.name("__ID"))

不幸的是,列名中的__ 无法避免,因为数据是从关系数据库 (FileMaker) 下载的,需要在保留列名的同时写回数据库。

关于[[的参考:

R 中重构的参考资料:

【问题讨论】:

  • 老实说,我不会过多担心重构您的代码。您可能会在重构中引入更多错误,而不是离开它可能会遇到的错误。我只花了 20 分钟试图开始,我能想到的最好的方法是在所有常见情况下都无法正常工作,更不用说边缘情况了。 library(stringr) test &lt;- c("x &lt;- df$var_name\n", "x &lt;- df$var_name", "x &lt;- df$var_name ") str_replace(test, pattern = "([$])(.+)(\n|[!\"#$%&amp;()*+,-./:;&lt;=&gt;?@^`{|}~])", replace = "[[\"\\2\"]]\\3")
  • 我赞同@Benjamin 的评论。仅修复现有代码中的重要内容,并使用您新发现的常用习语继续前进。您的$ 填充代码没有错误也没有损坏。将有限的时间资源花在新的和重要的事情上。
  • 感谢@Benjamin 和@hrbmstr,感谢您的cmets。在这里,重构的目的只是故事的一部分,而不仅仅是为了代码的可读性。实际上我更喜欢$ 的可读性,即使它有反引号符号。我的主要目标是允许将列名作为变量传递(即使它们以 _ 开头,并且使用不包含反引号符号的标准字符串更容易。)这有意义吗?现在有反引号的部分是硬编码的,我将转向动态计算它们。

标签: r list rstudio filemaker textwrangler


【解决方案1】:

你可以试试:

v <- c("l$`__a`$`__ID`")

library(stringi)
stri_replace_all_fixed(v, c('$`', '`'), c('[["', '"]]'), vectorize_all = FALSE)

这给出了:

#[1] "l[[\"__a\"]][[\"__ID\"]]"

注意:您会在输出中看到\",因为print() 在显示引号时会对其进行转义。您可以将上述内容包装在noquote() 中以查看没有\" 的输出

noquote(
  stri_replace_all_fixed(v, c('$`', '`'), c('[["', '"]]'), vectorize_all = FALSE)
)

这给出了:

#[1] l[["__a"]][["__ID"]]

如果您想将此应用于整个文件,您可以尝试:

writeLines(stri_replace_all_fixed(readLines("script.R"), 
                                  c('$`', '`'), c('[["', '"]]'), vectorize_all = FALSE),
           file("new_script.R"))

【讨论】:

  • 这看起来非常令人鼓舞。你知道如何将它应用到整个 .r 文件吗?
  • @Bobby 也许stri_replace_all_fixed(readLines("script.R"), c('$', ''), c("[['", "']]"), vectorize_all = FALSE) ?
  • 我仍然认为这对于我的问题的特定部分来说是一个很棒的答案。对于一般部分,我还不确定。如何确保我没有不应替换的反引号?
  • @Bobby 我认为我们可以使用更强大的正则表达式方法来确保我们只在之前有 $backtick 的情况下更改反引号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多