stats134711
stats134711

Reputation: 636

Removing specific element from a list of vectors in R

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.

Upvotes: 2

Views: 401

Answers (2)

Martin Morgan
Martin Morgan

Reputation: 46856

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).

Upvotes: 2

thelatemail
thelatemail

Reputation: 93813

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

Upvotes: 1

Related Questions