在 R 看门人包中使用 `make_clean_names` 保留重复项

keep duplicates using `make_clean_names` in R janitor package

我正在尝试使用 janitor R 包中的 make_clean_names 函数来 清理一个字符列 。在这种情况下,我需要保留重复项,并且不要向其添加数字。这可能吗?我的代码是这样的

x <- c(' x y z', 'xyz', 'x123x', 'xy()','xyz','xyz')

janitor::make_clean_names(x)
[1] "x_y_z" "xyz"   "x123x" "xy"    "xyz_2" "xyz_3"

janitor::make_clean_names(x, unique_sep = '.')
[1] "x_y_z" "xyz"   "x123x" "xy"    "xyz.1" "xyz.2"

janitor::make_clean_names(x, unique_sep = NULL)
[1] "x_y_z" "xyz"   "x123x" "xy"    "xyz_2" "xyz_3"

使用unique_sep = NULL 似乎不起作用。还有其他保持唯一值的方法吗?

期望的输出:

[1] "x_y_z" "xyz"   "x123x" "xy"    "xyz" "xyz"

我知道如何使用正则表达式来做到这一点。只是在寻找捷径。

PS:我知道创建此函数是为了清理 data.frame 的名称,我正在尝试将其应用于不同的用例。此功能可能对清理字符列有很大帮助。

很遗憾,不,这是不可能的。如果您查看 make_clean_names 的代码,您会看到它以这样的结尾:

 # Handle duplicated names - they mess up dplyr pipelines.  This appends the
  # column number to repeated instances of duplicate variable names.
  while (any(duplicated(cased_names))) {
    dupe_count <-
      vapply(
        seq_along(cased_names), function(i) {
          sum(cased_names[i] == cased_names[1:i])
        },
        1L
      )
  
    cased_names[dupe_count > 1] <-
      paste(
        cased_names[dupe_count > 1],
        dupe_count[dupe_count > 1],
        sep = "_"
      )
  }

我认为您将 unique_sep 参数传递给 make_clean_names 使用的基础函数 snakecase::to_any_case 是正确的。但是最近引入的 while 循环是为了确保 永远不会 make_clean_names 产生的重复名称,将始终在最后删除重复数据。

您可以尝试调整您自己的函数,即 make_clean_names 的第一部分,而不使用循环,或者您可以使用 snakecase::to_any_case.

您可以使用 sapply 逐个遍历向量元素,从而避免向重复项添加数字后缀:

sapply(x, make_clean_names, USE.NAMES = F)
[1] "x_y_z" "xyz"   "x123x" "xy"    "xyz"   "xyz"