比方说,我的数据有两个相同的列,称为SYC SJ Equity。当我使用基数read.csv()
将其导入R并将check.names
设置为FALSE
到R中时,数据被导入具有相同名称的两列。然后,我可以像这样删除重复的列:
df <- df %>%
do(.[!duplicated(names(.))])
如果我使用读取器中的read_csv()
函数来导入数据,则重复的列将以“ SYC SJ Equity_1”的形式获得列名。然后,我可以执行以下操作以删除重复的列
df <- df %>%
select(-contains("_"))
但是,如果数据以.xlsx
格式存在于工作表中,并且我使用read_excel()
包中的readxl
函数,则重复的列将导入为:
New names:
* `SYC SJ Equity` -> `SYC SJ Equity...406`
* `SYC SJ Equity` -> `SYC SJ Equity...407`
在这种情况下,两列都被重命名,而使用read_csv()
,仅多余的实例被重命名。在这种情况下,我必须匹配整个字符串才能删除重复的列。我不知道哪些数字将分配给重复的列。我认为它是基于列索引的?此外,即使使用read_csv()
导入,如果我的列在原始数据中的名称中自然都带有下划线,那么我的解决方案将无法使用。所以我的问题是,如何删除tidyverse中带有重复存储的数据的重复列?对于底数为R的duplicated()
,这很容易。但这不适用于tidyverse的修改。我知道dplyr
动词是按列名而不是按列索引选择的,因此列名始终必须不同。但是,有没有一种方法可以始终使用tidyverse删除重复的列,而无需查看控制台来查看新的重复的名称?
答案 0 :(得分:2)
让我们假设您没有名称实际包含3个点(...
)的列。我们可以将数据读入R并从名称中删除这3个点,使用duplicated
查找重复的名称并选择唯一列。
df[, !duplicated(sub("\\.\\.\\..*", "", names(df)))]
只是展示它如何在向量上工作
x <- c("y", "SYC SJ Equity...406", "SYC SJ Equity...407", "x")
x[!duplicated(sub("\\.\\.\\..*", "", x))]
#[1] "y" "SYC SJ Equity...406" "x"
因此,它会按原样保留"x"
和"y"
列,并仅选择第一个重复的值。
答案 1 :(得分:2)
以罗纳克(Ronak)提供的答案为基础,如果您想在dplyr
中这样做,则可以将其提供的解决方案与select_if
一起使用。
library(dplyr)
df <- data.frame("x" = runif(3),
"SYC SJ Equity...406" = c("a", "a", "b"),
"SYC SJ Equity...407" = c("a", "a", "b"),
"y" = runif(3))
df %>%
select_if(!duplicated(sub("\\.\\.\\..*", "", names(.))))
答案 2 :(得分:1)
或者使用select_if
和str_remove
library(stringr)
library(dplyr)
df %>%
select_if(!duplicated(str_remove(names(.), '\\..*')))