【问题标题】:Function that ignores missing columns忽略缺失列的函数
【发布时间】:2017-10-05 13:41:00
【问题描述】:

假设我有以下两个数据框:

col1 <- c("a","b","c","d","e")
col2 <- c("A","B","C","D","E")

col1a <- c("a","b","c","d","e")
col2a <- c("A","B","C","D","E")

df1 <- data.frame(col1, col2)
df2 <- data.frame(col1a, col2a)

colnames(df1) <- c("c1","c2")
colnames(df2) <- c("c1","c3")

我有以下功能来重命名列标题:

library(dplyr)

col_rename <- function(x) x %>% rename(new_c1 = c1, new_c2 = c2, new_c3 = c3)

当我运行这个函数时,我得到一个错误,因为函数中的列与数据框中的列不匹配。

df1 <- col_rename(df1)
Error: `c3` contains unknown variables 

如何使函数仅在当前列上运行,而忽略不存在的列,而不删除或更改函数中指定的列名?

编辑:

我可以看到这个例子有点令人困惑。我有许多包含许多列的数据框。这些列由一些数据框共享,但不是全部。但是,我想重命名函数指定的所有列,而不管数据框中存在什么。它看起来像这样:

col1 <- c(1:5)
col2 <- c(1:5)
col3 <- c(1:5)
col4 <- c(1:5)


df1 <- data.frame(col1,col2,col3,col4)
df2 <- data.frame(col1,col2,col3,col4)

colnames(df1) <- c("c1","c2","c6","c8")
colnames(df2) <- c("c1","c3","c2","c8")

AB_rename <- function(x) x %>% rename(aa=col1,bb=col2,                      
                                      cc=col3,dd=col4,
                                      ee=col5,ff=col6,
                                      gg=col7,hh=col8)

因此我不能效仿@Ycw 的例子,因为它们并不都遵循相同的重命名规则。如何让它忽略不存在的列?

【问题讨论】:

标签: r dplyr


【解决方案1】:

这里是使用setNames 来实现col_rename 函数的解决方法。

col_rename <- function(x) setNames(x, paste0("new_", names(x)))

col_rename(df1)
  new_c1 new_c2
1      a      A
2      b      B
3      c      C
4      d      D
5      e      E

col_rename(df2)
  new_c1 new_c3
1      a      A
2      b      B
3      c      C
4      d      D
5      e      E

或者使用dplyr中的select_all函数。

library(dplyr)

df1 %>% select_all(function(x) paste0("new_", x))
  new_c1 new_c2
1      a      A
2      b      B
3      c      C
4      d      D
5      e      E

这 (~) 也适用于 select_all

df2 %>% select_all(~paste0("new_", .))
  new_c1 new_c3
1      a      A
2      b      B
3      c      C
4      d      D
5      e      E

rename_all 也很好用

library(dplyr)

df1 %>% rename_all(~paste0("new_", .))
  new_c1 new_c2
1      a      A
2      b      B
3      c      C
4      d      D
5      e      E

更新

这是解决 OP 更新问题的更新。

我们可以创建一个命名向量来显示旧列名和新列名之间的关系。并根据setNames函数定义了改名的函数。

# Create name vector
vec <- paste0("c", 1:8)
names(vec) <- c("aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh")

# Create the function
AB_rename <- function(x, name_vec){
  old_colname <- names(x)
  new_colname <- name_vec[name_vec %in% old_colname]
  x2 <- setNames(x, names(new_colname))
  return(x2)
}

AB_rename(df1, vec)
  aa bb ff hh
1  1  1  1  1
2  2  2  2  2
3  3  3  3  3
4  4  4  4  4
5  5  5  5  5

【讨论】:

  • @d.b 感谢您的评论。你想name_vec[match(old_colname, name_vec)]吗?
猜你喜欢
  • 2021-09-18
  • 2020-08-11
  • 2020-03-23
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多