8

I need to gather_ on all columns of a dataframe, except for one. Example:

# I want to generate a dataframe whose column names are the letters of the alphabet. If you know of a simpler way, let me know!
foo <- as.data.frame(matrix(runif(100), 10, 10))
colnames(foo) <- letters[1:10]

Now, suppose I want to gather on all columns except column e. This won't work:

mycol <- "e"
foo_melt <- gather_(foo, key = "variable", value = "value", -mycol)
#Error in -mycol : invalid argument to unary operator

This will:

column_list <- colnames(foo)
column_list <- column_list[column_list != mycol]
foo_melt <- gather_(foo, key = "variable", value = "value", column_list)

Looks quite convoluted if you ask me. Isn't there any simpler way?

DeltaIV
  • 4,773
  • 12
  • 39
  • 86
  • 2
    One option is `setdiff` i.e. `gather_(foo, key = "variable", value = "value", setdiff(names(foo), mycol))` – akrun Nov 22 '16 at 16:43

2 Answers2

11

One option is one_of with gather

res1 <- gather(foo, key = "variable", value = "value", -one_of(mycol))

and if we need gather_, then setdiff can be used

res2 <- gather_(foo, key = "variable", value = "value", setdiff(names(foo), mycol))

identical(res1, res2)
#[1] TRUE
dim(res1)
#[1] 90  3

head(res1, 3)
#          e variable     value
#1 0.8484310        a 0.2730847
#2 0.0501665        a 0.8129584
#3 0.6689233        a 0.5457884
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Fantastic! I don't even need `gather_` now - I used it because the variable on which to reshape is dynamic, but with `one_of` I can still use `gather`. – DeltaIV Nov 22 '16 at 17:19
2

Try this:

foo_melt <- gather_(foo, key = "variable", value = "value",names(foo)[-5])

This will give you all columns except the 5th ("e").

> head(foo_melt)
          e variable     value
1 0.6359394        a 0.9567835
2 0.1558724        a 0.7778139
3 0.1418696        a 0.2132809
4 0.7184244        a 0.4539194
5 0.4487064        a 0.1049392
6 0.5963304        a 0.8692680
hvollmeier
  • 2,956
  • 1
  • 12
  • 17