-2

I have a list where the columns all have the same length,

ll<-list("a"=c(1:5),
         "b"=c(1:5)*10,
         "c"="one","two","three","four","five")

and I would like to remove all rows where ll$c=="one". With dataframes I can use ll[- grep("one", ll$c),], but that doesn't work for lists.

Is there a way to generalize the method to work for lists as well?

BillyJean
  • 1,537
  • 1
  • 22
  • 39
  • 2
    Within a list, referring to a "row" is ambiguous; you could mean getting rid of the first element of `c` or getting rid of `c` altogether. You should really provide your desired result [to make your example reproducible](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example#5963610). – alistaire Jun 07 '17 at 15:29
  • 2
    Your `c` is malformed, you need `c = c("one", "two", ...))`. With the typo corrected, and wrapped in as.data.frame, I guess your code works, however, `grep` is dangerous since `-c()`, an empty grep, will give you the wrong subset. – Frank Jun 07 '17 at 15:30

1 Answers1

2

If all elements of you list are of the same length, maybe you should be using a data.frame. However, Assuming that you want to remove elements within each list element that correspond to the position where ll$c == "one", you could use the following lapply.

lapply(ll, "[", ll$c != "one")
$a
[1] 2 3 4 5

$b
[1] 20 30 40 50

$c
[1] "two"   "three" "four"  "five"

The second argument indicates the subsetting or extraction function, see ?"[" and the third argument is used to feed the subsetting function with a vector of logicals the same length as ll$c (and the rest of the list elements).

If there are many list elements, it would be more efficient to calculate the logical vector once initially and then refer to it repeatedly.

keepers <- ll$c != "one"
lapply(ll, "[", keepers)

data

ll <-
structure(list(a = 1:5, b = c(10, 20, 30, 40, 50), c = c("one", 
"two", "three", "four", "five")), .Names = c("a", "b", "c"))
lmo
  • 37,904
  • 9
  • 56
  • 69