24

I made a list out of my dataframe, based on the factor levels in column A. In the list I would like to remove that column. My head is saying lapply, but not anything else :P

$A
ID Test
A   1
A   1

$B
 ID Test
 B   1
 B   3
 B   5

Into this

$A
Test
 1
 1

$B
Test
 1
 3
 5
ego_
  • 1,409
  • 6
  • 21
  • 31

4 Answers4

53

Assuming your list is called myList, something like this should work:

lapply(myList, function(x) { x["ID"] <- NULL; x })

Update

For a more general solution, you can also use something like this:

# Sample data
myList <- list(A = data.frame(ID = c("A", "A"), 
                              Test = c(1, 1), 
                              Value = 1:2), 
               B = data.frame(ID = c("B", "B", "B"), 
                              Test = c(1, 3, 5), 
                              Value = 1:3))
# Keep just the "ID" and "Value" columns
lapply(myList, function(x) x[(names(x) %in% c("ID", "Value"))])
# Drop the "ID" and "Value" columns
lapply(myList, function(x) x[!(names(x) %in% c("ID", "Value"))])
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
  • thank you :) I think I'm beginning to see how to apply functions within lapply.. :) – ego_ Sep 30 '12 at 20:02
  • @EndreGrünerOfstad, no problem. See my updated answer for another option you can use. – A5C1D2H2I1M1N2O1R2T1 Sep 30 '12 at 20:25
  • @mrwab Thanks! Btw, do you know how to merge two lists with the same element structure? E.g. one goes from two lists where each element level contains one vector each to one list where each element level contains two vectors. Perhaps it should be a question all by itself.. – ego_ Sep 30 '12 at 20:37
  • The last column in each data frame does not have a column name. How can I use lapply to drop that last column without using the col. names? – derelict Jan 13 '16 at 20:17
  • 1
    @SoilSciGuy, use something like `x[length(x)] <- NULL` instead? – A5C1D2H2I1M1N2O1R2T1 Jan 14 '16 at 02:05
  • @AHandcartAndMohair thanks for the great answer ! What is the significance of the semi-colon in the function? I don't quite understand what that means. – vagabond Oct 18 '16 at 13:56
  • 1
    @vagabond, just to allow me to write two statements in the same line. If you didn't have the `; x` nothing would actually get returned.... – A5C1D2H2I1M1N2O1R2T1 Oct 18 '16 at 14:05
13

If you are tidyverse user there is an alternative solution, which utilizes map function from purrr package.

# Create same sample data as above
myList <- list(A = data.frame(ID = c("A", "A"), 
                              Test = c(1, 1), 
                              Value = 1:2), 
               B = data.frame(ID = c("B", "B", "B"), 
                              Test = c(1, 3, 5), 
                              Value = 1:3))
# Remove column by name in each element of the list
map(myList, ~ (.x %>% select(-ID)))
7

We can efficiently use the bracket function "[" here.

Example

L <- replicate(3, iris[1:3, 1:4], simplify=FALSE)  # example list

Delete columns by numbers

lapply(L, "[", -c(2, 3))

Delete columns by names

lapply(L, "[", -grep(c("Sepal.Width|Petal.Length"), names(L[[1]])))

Result

# [[1]]
#   Sepal.Length Petal.Width
# 1          5.1         0.2
# 2          4.9         0.2
# 3          4.7         0.2
# 
# [[2]]
#   Sepal.Length Petal.Width
# 1          5.1         0.2
# 2          4.9         0.2
# 3          4.7         0.2
Community
  • 1
  • 1
jay.sf
  • 60,139
  • 8
  • 53
  • 110
3

If you had a data frame that didn't contain the ID column, you could use map_if to remove it only where it exists.

myList <- list(A = data.frame(ID = c("A", "A"), 
                          Test = c(1, 1), 
                          Value = 1:2), 
           B = data.frame(ID = c("B", "B", "B"), 
                          Test = c(1, 3, 5), 
                          Value = 1:3),
           C = data.frame(Test = c(1, 3, 5), 
                          Value = 1:3))
map_if(myList, ~ "ID" %in% names(.x), ~ .x %>% select(-ID), .depth = 2)
Jenna Allen
  • 454
  • 3
  • 11