【问题标题】:Preserving many columns when using gather使用收集时保留许多列
【发布时间】:2016-04-13 16:14:13
【问题描述】:

我有一个非常宽的 df(85 列),我想使用 gather 将其转换为长格式。我没有使用-c(all the columns I do not want to gather) 语法来保留列,而是创建了列名的对象并得到了错误。

Error in -c(KeepThese) : invalid argument to unary operator

例如,使用带有一些附加字段的iris

require(tidyr)
iris$Season <- sample(c("AAA", "BBB"), nrow(iris), replace = T)
iris$Var <- sample(c("CCC", "DDD"), nrow(iris), replace = T)

> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Season Var
1          5.1         3.5          1.4         0.2  setosa    AAA DDD
2          4.9         3.0          1.4         0.2  setosa    AAA CCC
3          4.7         3.2          1.3         0.2  setosa    BBB CCC
4          4.6         3.1          1.5         0.2  setosa    BBB CCC
5          5.0         3.6          1.4         0.2  setosa    BBB DDD
6          5.4         3.9          1.7         0.4  setosa    AAA DDD

我想收集除 5:7 之外的所有列,它们被制成下面的一个对象。

KeepThese <- colnames(iris)[5:7]

现在,我想gather 除 5:7 之外的所有列,并调用 ID 列 Part 和数字字段 Value,并使用以下代码并得到错误。

dat <- iris %>% gather(Part, Value, -c(KeepThese))


Error in -c(KeepNames) : invalid argument to unary operator

如何指定一堆我不想收集的列而不在tidyr 中写出每一列?

添加为什么我的代码不起作用?

【问题讨论】:

    标签: r tidyr


    【解决方案1】:

    更新答案:正如 Hadley 评论中指出的那样,one_of() 就是您想要的。

    dat <- iris %>% gather(Part, Value, -one_of(KeepThese))
    

    原答案:

    另一种选择是使用as.name()。我们可以根据要保留的列名创建名称分类对象列表。然后使用do.call(c, ...)将其插入gather()

    dat <- iris %>% gather(Part, Value, -do.call("c", lapply(KeepThese, as.name)))
    head(dat)
    #   Species Season Var         Part Value
    # 1  setosa    AAA CCC Sepal.Length   5.1
    # 2  setosa    AAA CCC Sepal.Length   4.9
    # 3  setosa    AAA DDD Sepal.Length   4.7
    # 4  setosa    AAA CCC Sepal.Length   4.6
    # 5  setosa    AAA CCC Sepal.Length   5.0
    # 6  setosa    AAA DDD Sepal.Length   5.4
    

    或者,一个简单的 %in%which() 也可以做到(与 jbaums 的回答非常相似)。

    iris %>% gather(Part, Value, -which(names(.) %in% KeepThese))
    

    【讨论】:

    • 或者只使用 one_of()
    【解决方案2】:

    您可以使用match(或首先将列号传递给gather):

    dat <- iris %>% gather(Part, Value, -(match(KeepThese, colnames(.))))
    head(dat)
    
    ##   Species Season Var         Part Value
    ## 1  setosa    BBB DDD Sepal.Length   5.1
    ## 2  setosa    AAA CCC Sepal.Length   4.9
    ## 3  setosa    BBB CCC Sepal.Length   4.7
    ## 4  setosa    AAA CCC Sepal.Length   4.6
    ## 5  setosa    BBB DDD Sepal.Length   5.0
    ## 6  setosa    BBB CCC Sepal.Length   5.4
    

    【讨论】:

      【解决方案3】:

      指定列-matches 和一个好的正则表达式工作

      dat <- iris %>% gather(Part, Value, -matches(paste(KeepThese, collapse="|")))
      

      【讨论】:

        猜你喜欢
        • 2014-04-23
        • 1970-01-01
        • 2015-05-12
        • 2023-03-18
        • 1970-01-01
        • 2016-09-12
        • 2015-06-15
        • 2012-02-05
        • 1970-01-01
        相关资源
        最近更新 更多