1

An easy one I suppose though my searches have been pretty fruitless --

given

z=data.frame(X.39=rnorm(20),X.40=rnorm(20),X.51=rnorm(20))

the subsetting operation

z[,c('X.39','X.51')]

works. but

z[,-c('X.39','X.51')]

gives me

Error in -c("X.39", "X.51") : invalid argument to unary operator

why is that and how do I remove a set of columns using a list of column names?

EDIT

I know that I can always use

z[,!names(z) %in% c('X.39','X.51')]

but I'm looking for a lazier solution

EDIT2

Most of the discussion has been in the comment section but to close this off for good order, the gist of this is that a lazier solution (direct reference by name) is not possible. This appears to be designed in.

Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
Tahnoon Pasha
  • 5,848
  • 14
  • 49
  • 75
  • 1
    Use `z[, !names(z) %in% c('X.39, 'X.51'), drop = FALSE]`. The `drop=FALSE` is to ensure that you return a `data.frame` even if the result *after subsetting* is only one column. By default, if the result is 1 column, then a vector is returned. – Arun Apr 08 '13 at 06:14
  • hi @Arun, you just beat me to it. Please see edit above. Looking for a more elegant fix and don't understand why referencing by labels works one way and not the other – Tahnoon Pasha Apr 08 '13 at 06:15
  • 1
    `-which` is not recommended, as [this answer](http://stackoverflow.com/a/5236518/697568) illustrates. – Blue Magister Apr 08 '13 at 06:16
  • @BlueMagister, I was just about to write the same. – Arun Apr 08 '13 at 06:17
  • Hi @BlueMagister this isn't a duplicate. I know how to delete a column, I want to know why the subset by column label works to select but not to deselect and how to fix it. – Tahnoon Pasha Apr 08 '13 at 06:17
  • This is a duplicate, but I suspect if it's to the one BlueMagister linked. – Arun Apr 08 '13 at 06:17
  • 1
    Possibly this one as well: [How to drop columns by name in a data frame](http://stackoverflow.com/questions/5234117/how-to-drop-columns-by-name-in-a-data-frame) – Blue Magister Apr 08 '13 at 06:18
  • 1
    This one: [removing a list of columns from a data.frame using subset](http://stackoverflow.com/questions/9845929/removing-a-list-of-columns-from-a-data-frame-using-subset/9846035#9846035) (in spite of the subset, the answer's valid here) – Arun Apr 08 '13 at 06:19
  • The deselect doesn't work because the unary operator `-` on character vectors is not defined. The operation `-"a"` does not make sense in R. – Blue Magister Apr 08 '13 at 06:22
  • @Arun and BlueMagister. Looked at both and both solutions are longer than my edited one and neither address why `-c('X.39')` wont work. I accept the `!names(x)` being superior to `which(colnames(x))` formulation, but I think I'm asking a different question here so I still don't think its a duplicate. The how to drop columns by name aspect may be a red herring in this case. – Tahnoon Pasha Apr 08 '13 at 06:24
  • @Arun, if you repost your response as an answer I'll select it. It looks like the shortest solution there is and the answer to my question per BlueMagister seems to be 'thats just the way it is'. Its useful to know that its a design feature in any case. Not sure I see the 'why' of it but that isn't too significant really. – Tahnoon Pasha Apr 08 '13 at 06:37
  • @Arun on bluemagisters comment - I think it explains it but I don't see the effect as anything but a design choice. There isn't anything intrinsically special about a '-' sign. +"a" makes no more sense than -"a" but that works, because the reference is to a vector by name not to a character itself. – Tahnoon Pasha Apr 08 '13 at 22:33
  • 1
    @TahnoonPasha, try: `df <- data.frame(x=1:5, y=6:10)`; `df[, +c("x")]` – Arun Apr 08 '13 at 22:34
  • @Arun I take your point, but df[,c("x")] does. So the positive valence is okay or R. Don't have R open but will check if df[,+c(2)] works later. My understanding of the subset notation was that df[,-c(2)] would be shorthand for 'without column 2' not subtract column two. I'm sure the answer is right but I don't feel any better informed about why the phenomenon exists. – Tahnoon Pasha Apr 08 '13 at 22:43
  • Even better: just try `+"x"` and `-"x"` in R. you'll get the same error. I don't have much time to write in detail about this. You'll have to look into R documentation (the question is closed even if I wanted to write a detailed answer). – Arun Apr 08 '13 at 22:56

1 Answers1

2

You could use setdiff function, but I can't say if its the most elegant solution:

z[, setdiff(names(z), c('X.39','X.51'))]
Nishanth
  • 6,932
  • 5
  • 26
  • 38