R: использование значений из данных.рамка для подмножества элементов списка с помощью lapply


У меня есть список, содержащий годовые данные об обилии видов для различных водно-болотных угодий (каждый элемент списка-это разные водно-болотные угодья). Элементы имеют столбцы = виды и строки = год съемки. Я хочу подмножествовать каждый элемент по-разному, используя функцию lapply, чтобы захватить 3 года данных, определенных отдельными данными.рамка. Ниже приведен код для генерации данных:

set.seed(1)
df <- data.frame(year=c("x00", "x01", "x02", "x03", "x04", "x05"), 
                               mean=c(12, 10, 13, 10, 9, 11), 
                               sd=c(1, 2, 3, 1, 3, 2))
normv <- function( n , mean , sd ){
        out <- rnorm( n*length(mean) , mean = mean , sd = sd )
        return( matrix( out , , ncol = n , byrow = FALSE ) )
        }
com1 <- round(normv( 10 , df$mean , df$sd ),0)
row.names(com1) <- df$year
colnames(com1) <- c("sp1", "sp2", "sp3", "sp4", 
    "sp5", "sp6", "sp7", "sp8", "sp9", "sp10")

com2 <- round(normv( 10 , df$mean , df$sd ),0)
row.names(com2) <- df$year
colnames(com2) <- c("sp1", "sp2", "sp3", "sp4", "sp5", 
    "sp6", "sp7", "sp8", "sp9", "sp10")

com3 <- round(normv( 10 , df$mean , df$sd ),0)
row.names(com3) <- df$year
colnames(com3) <- c("sp1", "sp2", "sp3", "sp4", "sp5", 
    "sp6", "sp7", "sp8", "sp9", "sp10")

com.list <- list(com1, com2, com3)

years <- data.frame(rbind(c("x00", "x01", "x02"), c("x03", "x04", "x05"), 
    c("x02", "x03", "x05")))
colnames(years) <- c("com1", "com2", "com3")

Я пытался что-то вроде:

library(data.table)
lapply(com.list, function(x){
    x.sub <- data.table::setDT(data.frame(x))[
        row.names(x) %chin% as.character(years[,x])]
    return(x.sub)
}

Любая помощь была бы очень признательна! Крис

1 2

1 ответ:

Если мы ищем подмножество, основанное на соответствующем столбце 'years', то мы можем использовать Map из base R

Map(function(x, y) subset(x, row.names(x) %in% y), com.list, years)

Если мы хотим использовать lapply, то цикл через последовательность list и затем подмножество 'years' и 'com.список", основанный на этом

lapply(seq_along(com.list), function(i) {
          dat <- com.list[[i]]
          subset(dat, row.names(dat) %in% years[,i])
 })

Вариант tidyverse будет

library(tidyverse)
map2(com.list, years, ~  .x %>%
                           as.data.frame %>% 
                           filter(row.names(.) %in% .y))