【问题标题】:Renaming data frame column variables without using column name在不使用列名的情况下重命名数据框列变量
【发布时间】:2018-03-18 07:37:39
【问题描述】:

我想创建一个函数,将列中的特定值重命名为由函数指定的其他值,类似这样(尽管实际上还有更多需要重命名):

func <- function(x) x %>%
                    mutate(col_name = ifelse(col_name =="something","something else", 
                                      ifelse(col_name == "something2","something_else2")))

请注意,我要更改的不是列名,而是列中的值本身。但是,无论值在哪个列中,我都希望它能够工作(例如,该函数在整个数据框中工作)。此外,这仅在函数中命名的值存在时才有效,并且我希望它忽略列中不存在的值。这是一个可重现的小例子:(列值是任意的)

col1 <- c("a","b","c","d","e")
col2 <- c("b","f","d","c","g")

df <- data.frame(col1, col2)

col3 <- c("a","h","i","b","c")
col4 <- c("c","d","j","a","g")

df2 <- data.frame(col3, col4)

看起来像这样:

df1:
  col1 col2
1    a    b
2    b    f
3    c    d
4    d    c
5    e    g

df2:
  col3 col4
1    a    c
2    h    d
3    i    j
4    b    a
5    c    g

说我想这样重命名:

df1:

   col1 col2
1  can  chi
2  chi  pig
3  equ  she
4  she  equ
5  fox  bov

df2:

   col3 col4
1  can  equ
2  avi  she
3  tyr  asp
4  chi  can
5  equ  bov

所以我希望得到一个函数,它可以更改数据框列中多个值的名称,而不管其在数据框中的位置如何,并且它会忽略该函数在数据框中未找到的值。

【问题讨论】:

  • 您能用所需的输出编辑问题吗?
  • 我很困惑;您想重命名变量,但不更改列名?在通常的数据框中,每一列都是一个变量,所以它们是相同的。您能否在可重现的示例中添加您希望输出的内容?
  • 我认为您将“变量”与列的“记录/值/条目/元素”混淆了。在 R 中,列一个变量。如果你想引用列内的东西,你通常会称它们为“元素”或“值”。
  • 感谢您的反馈,我对编程很陌生。我已经编辑了问题并更改了一些单词,并添加了我想要得到的结果。
  • @Haakonkas 很好地提供了一个可重现的例子!看看我的回答是否令人满意。顺便说一句,您的df2 好像有错字,col4 的第一行应该是equ

标签: r dataframe dplyr rename


【解决方案1】:

重新编码所有列

library(dplyr)
func = function(x, originals = letters[1:10], 
                rename_tos = c("can", "chi", "equ", "she", "fox", "pig", "bov", "avi", "tyr", "asp")){
  names(rename_tos) = originals
  x %>%
    mutate_if(is.factor, as.character) %>%
    lapply(function(y){
      y = rename_tos[y]
    }) %>%
    data.frame(row.names = NULL) 
}

结果:

> func(df)
  col1 col2
1  can  chi
2  chi  pig
3  equ  she
4  she  equ
5  fox  bov

> func(df2)
  col3 col4
1  can  equ
2  avi  she
3  tyr  asp
4  chi  can
5  equ  bov

注意事项:

我使用的方法基本上是为重命名创建一个查找表(命名向量)并使用列值索引rename_tos 向量。在这里,我将原件和重命名设置为函数的默认值,但您也可以提供自己的。

用户提供的列名

如果您希望能够重命名指定的列并使其他列保持不变,您可以执行以下操作:

library(dplyr)
library(rlang)

func = function(x, ..., originals = letters[1:10], 
                rename_tos = c("can", "chi", "equ", "she", "fox", "pig", "bov", "avi", "tyr", "asp")){
  names(rename_tos) = originals
  dots = quos(...)
  x %>%
    mutate_at(vars(!!! dots), as.character) %>%
    mutate_at(vars(!!! dots), funs(rename_tos[.])) %>%
    data.frame(row.names = NULL) 
}

结果:

> func(df, col2)
  col1 col2
1    a  chi
2    b  pig
3    c  she
4    d  equ
5    e  bov

> func(df2, col3, col4)
  col3 col4
1  can  equ
2  avi  she
3  tyr  asp
4  chi  can
5  equ  bov

> func(df2, c(col3, col4))
  col3 col4
1  can  equ
2  avi  she
3  tyr  asp
4  chi  can
5  equ  bov

注意事项:

在这里,我添加了... 参数以允许用户输入他们自己的列名。我使用rlang 中的quos 引用... 参数,然后使用!!!varsmutate_at 中取消引用它们。例如,如果用户提供了func(df, col2),则mutate_at 的第一个参数的计算结果为vars(col2)。这适用于多个参数以及可以在结果中看到的参数向量。

【讨论】:

  • 感谢您的回答!这似乎可行。但是,我的数据框也包含其他包含数据的列,这似乎将所有其他值转换为 NA 而不是忽略它们。此外,它将数据框保存为一个值。您将如何继续并使其忽略数据框中的其他值,可能使用 gsub(regEx 匹配多个列),或者添加一些使其仅适用于包含“原始”值的列的内容?跨度>
  • @Haakonkas 查看我的更新。这应该会给你你想要的。
  • 这太棒了!完美运行!谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 2014-12-07
  • 1970-01-01
  • 2017-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多