user3347232
user3347232

Reputation: 427

Drop last 5 columns from a dataframe without knowing specific number

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

Answers (6)

AndrewGB
AndrewGB

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

Sinossisus
Sinossisus

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

David Arenburg
David Arenburg

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

rnso
rnso

Reputation: 24555

length(df) can also be used:

mydf[1:(length(mydf)-5)]

Upvotes: 23

Simon O&#39;Hanlon
Simon O&#39;Hanlon

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

EDi
EDi

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

Related Questions