Reputation: 427
I have a dataframe that is created by a for-loop with a changing number of columns.
In a different function I want the drop the last five columns.
The variable with the length of the dataframe is "units" and it has numbers between 10 an 150.
I have tried using the names of the columns to drop but it is not working. (As soon as I try to open "newframe" R studio crashes, viewing myframe is no problem).
drops <- c("name1","name2","name3","name4","name5")
newframe <- results[,!(names(myframe) %in% drops)]
Is there any way to just drop the last five columns of a dataframe without relying on names or numbers of the columns
Upvotes: 13
Views: 38767
Reputation: 16856
A tidyverse
option is to use last_col
, where we first select the fifth column from the last column (i.e., last_col(offset = 4)
) then to the last column number. Then, we use the -
to remove the selected columns.
library(tidyverse)
df %>%
select(-(last_col(offset = 4):last_col()))
Output
x y z
1 1 10 5
2 2 9 5
3 3 8 5
4 4 7 5
5 5 6 5
6 6 5 5
7 7 4 5
8 8 3 5
9 9 2 5
10 10 1 5
Another option is to use ncol
in the select
:
df %>%
select(-((ncol(.) - 4):ncol(.)))
Or we could use tail
with names
:
df %>%
select(-tail(names(.), 5))
Data
df <- structure(list(x = 1:10, y = 10:1, z = c(5, 5, 5, 5, 5, 5, 5,
5, 5, 5), a = 11:20, b = c("a", "b", "c", "d", "e", "f", "g",
"h", "i", "j"), c = c("t", "s", "r", "q", "p", "o", "n", "m",
"l", "k"), d = 30:39, e = 50:59), class = "data.frame", row.names = c(NA,
-10L))
Upvotes: 3
Reputation: 1
If you are using data.table
package for your data processing, one nice way can be
drops <- c("name1","name2","name3","name4","name5")
df[, .SD, .SDcols=!drops]
In fact, this allows you to drop any variables as you like.
Upvotes: 0
Reputation: 92292
My preferable method is using rev
which makes the syntax cleaner. For mtcars
data set
mtcars[-rev(seq_len(ncol(mtcars)))[1:5]]
Or using head
(similar to Simons suggestion)
mtcars[head(seq_len(ncol(mtcars)), -5)]
Upvotes: 2
Reputation: 59970
Yo can take advantage of the list
method for head()
(which drops whole list elements, and works differently to the data.frame
method which drops rows):
# data.frame with 26 columns (named a-z):
df <- setNames( as.data.frame( as.list(1:26)) , letters )
# drop last 5 'columns':
as.data.frame( head(as.list(df),-5) )
# a b c d e f g h i j k l m n o p q r s t u
#1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Upvotes: 2
Reputation: 13280
You could use the counts of columns (ncol()
):
df <- data.frame(x = rnorm(10), y = rnorm(10), z = rnorm(10), ws = rnorm(10))
# rm last 2 columns
df[ , -((ncol(df) - 1):ncol(df))]
# or
df[ , -seq(ncol(df)-1, ncol(df))]
Upvotes: 3