我有一个数据集df,里边有重复的列名“depth”,我想用filter筛选其中一些行,

filter(df,result=="Ⅰ")

报错,提示depth不能复制。
Error: Column names depth, depth must not be duplicated.
Use .name_repair to specify repair.
Run rlang::last_error() to see where the error occurred.

rlang::last_error()
<error/rlang_error>
Column names depth, depth must not be duplicated.
Use .name_repair to specify repair.
Backtrace:

  1. dplyr::filter(tmp, result == "Ⅰ")
  2. dplyr:::filter.data.frame(tmp, result == "Ⅰ")
  3. dplyr::tbl_df(.data)
  4. tibble:::as_tibble.data.frame(data, .name_repair = "check_unique")
  5. tibble:::as_tibble.list(unclass(x), ..., .rows = .rows, .name_repair = .name_repair)
  6. tibble:::lst_to_tibble(x, .rows, .name_repair, col_lengths(x))
  7. tibble:::set_repaired_names(x, .name_repair)
  8. tibble:::repaired_names(names(x), .name_repair = .name_repair)
  9. tibble:::check_unique(new_name)
    Run rlang::last_trace() to see the full context.

当然这个有变通办法,df[df$result=="Ⅰ",]是可以达到我要的目的的,但是不能用filter这种舒服的方法,总是憋得难受,如果我不想去处理df的数据集的重复列,filter就不能用吗?

    dapengde
    列名有重复,净土不开心,楼主问那不改列名能不能用dplyr::filter

    tjt2008
    没有办法直接处理重复列。
    可以自己重命名或者janitor::clean_names
    以后,再用filter_at或者filter_all

      tjt2008 这个问题,在这里有清晰的答案 <https://design.tidyverse.org/names-attribute.html#minimal-unique-universal> Hadley 本人明确指出不可以这样,不符合 tidyverse 设计,这个设计明显在强调一致性,如果列名允许重复就不能实现后续数据操作(整个 dplyr 包提供的操作)的一致性。比如 select 操作就要崩溃了,我到底选择哪一列, Base R 的处理就是默认选择第一列,但是逻辑上不是很正确

      类似的跟一致性有关的帖子有

      解决数据处理的一致性是我最喜欢 tidyverse 的地方,唯一美中不足的是引入太多的依赖和主力的 R 包(dplyr 和 tidyr)的重要函数在不停地变化,我基本上在生产环境里都不用 tidyverse,而在那种一锤子买卖的情况下,用起来还是很爽的,写完就跑!

        Cloud2016

        同意

        数据分析的工作其实基本都是一锤子买卖,我用起tidyverse才肆无忌惮胆子贼大。

        filter的筛选也涉及到行和列,确实存在这样的问题或风险。
        我这个数据集使用cbind合并来的,感觉应该在cbind这一步就解决掉这个问题。

        业余的数据分析,就是工作中虽然经常做数据分析,但数据分析往往是解决实际问题的一个方式或手段,所以经常性不会顾及是否周全,更多的是考虑易用性和便捷,所以tidyverse从一诞生开始,就成了我用的主力,毕竟加载一次,全程无忧,比起用python舒服得多。
        现在看来,能用基础函数的时候,尽量少用新包,我记得read_csv刚出来的时候,读的数据超过100行以后,数据的位数有变化的时候,读入的数据就有个比较严重的bug,read.csv就没有问题。

        感谢楼上出镜的各位大佬,明白是怎么回事了,感谢!

          tjt2008 更改标题为「[已解决]filter确实不能处理具有重复列的数据集

          frankzhang21
          我其实是希望能保留重复的列名的,因为我是很多个子集合并来的,用cbind(file1,file2,file3....),很适合我现在的应用场景,当然,能像janitor那样后面加个后缀作为列名也是可以的。

          另外,我实际上不是以这个重复的列名为key来合并的,所以其实不适合merge,我保留这个重复的列,是为了让我能清楚的观察对比不同的子集里体现的结论。

          frankzhang21 如果不想要重复列名的话,在 cbind外边套一个data.frame就可以了:data.frame(cbind(...))。重复列名会被自动重命名。

          merge 是用来合并有共同行或者列的两个数据框的,也就是要求两数据框的行集合或列集合的交集不空;如果没有共同行或列,则合并结果为 0。

            Liechi
            感谢大神,data.frame(cbind())
            我要的就是这个东东,谢谢谢谢!

            一般说来,直接data.frame(col1, col2,...)就可以。
            data.frame(cbind()) 这样的写法其实都可以用来作“谜面”,猜歇后语了:)我的意思是你如果已经有了由cbind得来的数据,但不想要重复列名,可以套个data.frame()来挽救;但如果是从头写,本不需要绕这个弯。之前没表达清楚,不好意思。

              Liechi
              原来是可以省略cbind()的...,直接data.frame(df1,df2,df3)
              又学了一点,谢谢。