2

Suppose I have a list of indices and values.

indx_list <- list(1,2,c(3,4),5,c(6,7,8)) val_list <- list(0.1,0.6,c(0.8,0.9),0.3,c(0.4,0.8,0.5)) 

I then want to update both lists by removing indices c(4,7) and the corresponding values c(0.9,0.5). This is pretty easily done using lapply and setdiff. For example:

indx_list_new <- lapply(indx_list,function(x) setdiff(x,c(4,7))) val_list_new <- lapply(val_list,function(x) setdiff(x,c(0.9,0.5))) 

However, I don't know beforehand what indices and corresponding values I will be removing.

set.seed(1234) indx_flag <- sample(seq(8),2) 

You can also see that some values are repeated (i.e. 0.8) so using setdiff might actually remove values at the wrong position.

Questions

1) I can still use lapply and setdiff to update indx_list, but how can I update the values in val_list?

2) Is lapply the most efficient solution here? I will have lists with thousands of elements, and each element can be a vector of hundreds of indices/values.

Edit

Each element in the list (highest level) actually has a particular meaning, so I'd like to keep the list structure.

0

2 Answers 2

2

Instead, arrange your data into a 'tidy' representation

df = data.frame( indx = unlist(indx_list), val = unlist(val_list), grp = factor(rep(seq_along(indx_list), lengths(indx_list))) ) 

where the operation is more-or-less transparent

base::subset(df, !indx %in% c(4, 7)) indx val grp 1 1 0.1 1 2 2 0.6 2 3 3 0.8 3 5 5 0.3 4 6 6 0.4 5 8 8 0.5 5 

Using subset() is similar to df[!df$indx %in% c(4, 7), , drop = FALSE]. (I used factor() to allow for empty groups, i.e., levels with no corresponding values).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I should add that I would prefer to keep the list structure since the elements at the highest level actually have a particular meaning.
The list structure is present in the grp column, so there's no loss of information. Rectangular data is easier to reason about compared to lists-of-lists, etc.
Yes, you could recover the list that way, but really I'm suggesting that you do not use lists at all. Just a suggestion.
1

Here's an attempt using relist and Map to remove the same points:

Map(`[`, val_list, relist(!unlist(indx_list) %in% c(4,7), indx_list)) #[[1]] #[1] 0.1 # #[[2]] #[1] 0.6 # #[[3]] #[1] 0.8 # #[[4]] #[1] 0.3 # #[[5]] #[1] 0.4 0.5 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.