N.Varela
N.Varela

Reputation: 910

R: How to subset a list by the names of another list using regex?

I want to subset this list (first part of the names are productnames needed for the subsetting):

C <- list("110.2000"=matrix(sample(1:10,9), nrow=3, ncol=3),
          "111.2000"=matrix(sample(1:10,9), nrow=3, ncol=3),
          "112.2000"=matrix(sample(1:10,9), nrow=3, ncol=3),
          "111.2001"=matrix(sample(1:10,9), nrow=3, ncol=3),
          "112.2001"=matrix(sample(1:10,9), nrow=3, ncol=3),
          "111.2002"=matrix(sample(1:10,9), nrow=3, ncol=3),
          "113.2000"=matrix(sample(1:10,9), nrow=3, ncol=3))
names <- list(c("A", "B", "C"), c("A", "B", "C"))
C <- lapply(C, function (x) {dimnames(x) <- names; return(x)})

based on the names (only productnames) of this one:

A <- list("111"=matrix(sample(1:10,9), nrow=3, ncol=3),
          "112"=matrix(sample(1:10,9), nrow=3, ncol=3))
names <- list(c("A", "B", "C"), c("A", "B", "C"))
A <- lapply(A, function (x) {dimnames(x) <- names; return(x)})

Therefore I need to temporally separate the element names of C (e.g. 111.2000 into 111). In a single extraction using regex I understood to use this:

foo <- "111.2000"
gsub("\\..*.","",foo)

But how to apply or lapply on my list to subset? I tried this, but is not really a subset and it doesn't work:

lapply(function(x) C, gsub("\\..*.","",names(C)))

My expected output would be:

$`111.2000`
  A  B C
A 1  8 6
B 3  4 9
C 7 10 5

$`112.2000`
  A  B C
A 6  4 9
B 1 10 7
C 5  8 3

$`111.2001`
  A  B C
A 8 10 7
B 3  9 6
C 2  1 4

$`112.2001`
  A B  C
A 3 6  7
B 1 2  4
C 8 9 10

Ideas? Thank you

Upvotes: 0

Views: 644

Answers (2)

bramtayl
bramtayl

Reputation: 4024

This might be easier if you convert your data to normal form first.

library(dplyr)
library(tidyr)

C_fix = 
  C %>%
  lapply(. %>% as.data.frame %>% add_rownames) %>%
  bind_rows(.id = "product_year") %>%
  separate(product_year,
           c("product", "year"))

A_fix = 
  A %>%
  lapply(. %>% as.data.frame %>% add_rownames) %>%
  bind_rows(.id = "product")

A_fix %>%
  select(product) %>%
  left_join(C_fix)

Upvotes: 0

David
David

Reputation: 10222

If I am not mistaken, there is no need for the apply-family.

# get names
A.nam <- names(A)
C.nam <- names(C)

# get the first part of the names
C.nam.p1 <- gsub("\\..*.","", C.nam)

# decide what parts to choose
C.choose <- C.nam.p1 %in% A.nam

# choose the parts
C.chosen <- C[C.choose]

C.chosen
# $`111.2000`
# A B C
# A 8 3 4
# B 5 6 2
# C 1 9 7
# 
# $`112.2000`
# A B C
# A  8 2 5
# B 10 7 6
# C  3 4 9
# 
# $`111.2001`
# A B C
# A 10 5 1
# B  8 4 6
# C  7 3 9
# 
# $`112.2001`
# A B C
# A 10 7 4
# B  3 9 8
# C  5 6 2
# 
# $`111.2002`
# A B  C
# A 8 4  1
# B 3 9  6
# C 7 2 10

Does that give you what you want?

Upvotes: 1

Related Questions