我有一个非常宽的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
?
添加为什么我的代码不起作用?
更新后的答案:正如哈德利的评论所述,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))