1

I am trying to remove a single column from a list of dataframes using lapply with the below code (want to remove column name "ID" from both df1 and df2). I receive the following error message when running through command prompt:

Error in eval(substitute(select), nl, parent.frame()) : object 'ID' not found Calls: lapply -> FUN -> subset.data.frame -> eval -> eval

Any thoughts as to why the code produces an error?

df1 <- data.frame(
 "Qty" = c(15,29,12,53),
 "Type"   = c("A","B","B","E"),
 "ID"   = c("x123","y121","x556","y119"))

df2 <- data.frame(
 "Qty" = c(5,92,25,31),
 "Type"   = c("I","L","Z","K"),
 "ID"   = c("p433","q232","y344","l598"))

df_list <- mget(ls(pattern= "^df"))

df_list <- lapply(df_list, function(x) subset.data.frame(x, select=-c(ID)))

list2env(df_list, .GlobalEnv)
Matt Gossett
  • 184
  • 3
  • 13

2 Answers2

5

Try this dplyr approach:

library(dplyr)         
#Data
df1 <- data.frame(
  "Qty" = c(15,29,12,53),
  "Type"   = c("A","B","B","E"),
  "ID"   = c("x123","y121","x556","y119"))

df2 <- data.frame(
  "Qty" = c(5,92,25,31),
  "Type"   = c("I","L","Z","K"),
  "ID"   = c("p433","q232","y344","l598"))

df_list <- mget(ls(pattern= "^df"))

df_list <- lapply(df_list, function(x) {x <- x %>% select(-ID)})

list2env(df_list, .GlobalEnv)

The output (which will be released to environment):

df_list
$df1
  Qty Type
1  15    A
2  29    B
3  12    B
4  53    E

$df2
  Qty Type
1   5    I
2  92    L
3  25    Z
4  31    K
Duck
  • 39,058
  • 13
  • 42
  • 84
  • I receive the following error. Error: Can't subset columns that don't exist. x Column `ID` doesn't exist. Maybe it's an issue with my configuration? – Matt Gossett Sep 21 '20 at 13:51
  • @MattGossett Check that all dataframes in your list have the column `ID`, use `lapply(yourlist,names)` and check that! – Duck Sep 21 '20 at 13:52
  • thanks! The code works when run through R Studio but not when run through command prompt. Not sure of the issue. This worked for me though lapply(df_list, function(i){i$ID <- NULL; i}) – Matt Gossett Sep 21 '20 at 14:01
  • @MattGossett It is a valid option too! Fantastic!!! – Duck Sep 21 '20 at 14:05
1

Base R solutions:

# Safer, directly specifying the name: 
Map(function(x){x[,names(x) != "ID"]}, df_list)

# If the data.frames have the same column order: 
lapply(df_list, "[", 1:2)
hello_friend
  • 5,682
  • 1
  • 11
  • 15