DelTrader
DelTrader

Reputation: 19

Create new list with condition of values (sublist) ​from another list in R

I have the list ListResiduals that looks like this:

ListResiduals
    OptionA   Value
          1       4
          2       0
          3       7
    OptionB   Value
          1       2
          2       2
          3       9
    OptionC   Value
          1       3
          2       2
          3       1

I need create a new list Watchlist with the names of the previous list where the last value is for example > 5, something like:

Watchlist
  OptionA 
  OptionB

I have the following code but it is creating a meaningless matrix for what I want.

    Watchlist <- sapply(ListResiduals, function(x) {
  (lapply(ListResiduals, tail, n = 1) > 5)
  })

Upvotes: 0

Views: 311

Answers (3)

andrew_reece
andrew_reece

Reputation: 21264

You can use map, filter, and discard:

library(purrr)

map(ListResiduals, function(df) filter(df, last(Value) > 5)) %>% discard(~!nrow(.))

*Used @bouncyball's ListResiduals (thank you)

Upvotes: 0

ThomasIsCoding
ThomasIsCoding

Reputation: 101034

I guess you can try

  • sapply + ifelse + na.omit
> na.omit(sapply(ListResiduals, function(x) ifelse(tail(x, 1)$Value > 5, names(x)[1], NA)))
[1] "OptionA" "OptionB"
  • Filter + sapply
> names(sapply(Filter(function(x) tail(x, 1)$Value > 5, ListResiduals), `[`, 1))
[1] "OptionA" "OptionB"

Data

> dput(ListResiduals)
list(structure(list(OptionA = 1:3, Value = c(4, 0, 7)), class = "data.frame", row.names = c(NA, 
-3L)), structure(list(OptionB = 1:3, Value = c(2, 2, 9)), class = "data.frame", row.names = c(NA,
-3L)), structure(list(OptionC = 1:3, Value = c(3, 2, 1)), class = "data.frame", row.names = c(NA,
-3L)))

Upvotes: 0

bouncyball
bouncyball

Reputation: 10761

Try this:

unlist(lapply(ListResiduals,
       FUN = function(d) names(d)[1][tail(d, 1)$Value > 5]))

# "OptionA" "OptionB" 

tail(d, 1)$Value > 5 checks if the last value of Value is > 5. We then select the first name of the data.frame (OptionA, OptionB, OptionC), but only keep that value if tail(d, 1)$Value > 5 is TRUE

Using unlist will return a character vector.

Data

ListResiduals <- 
  list(d1 = data.frame(OptionA = 1:3, Value = c(4, 0, 7)),
       d2 = data.frame(OptionB = 1:3, Value = c(2, 2, 9)),
       d3 = data.frame(OptionC = 1:3, Value = c(3, 2, 1)))

Upvotes: 2

Related Questions