2016-06-17 6 views
1

У меня есть список с тем же структурой для каждого члена в следующемR - Collapse в векторе же элемент списка

config <- NULL 

config[["secA"]] <- NULL 
config[["secA"]]$VAL <- 0 
config[["secA"]]$ARR <- c(1,2,3,4,5) 
config[["secA"]]$DF <- data.frame(matrix(c(1,5,3,8),2,2)) 

config[["secB"]] <- NULL 
config[["secB"]]$VAL <- 1 
config[["secB"]]$ARR <- c(1,3,2,4,9) 
config[["secB"]]$DF <- data.frame(matrix(c(2,6,1,9),2,2)) 

config[["secC"]] <- NULL 
config[["secC"]]$VAL <- 5 
config[["secC"]]$ARR <- c(4,2,1,5,8) 
config[["secC"]]$DF <- data.frame(matrix(c(4,2,1,7),2,2)) 

и мне нужно получить 3 векторов VAL, ARR и DF, каждый из которых каскадных элементов соответствующего члена. такие как

# VAL: 0,1,5 
# ARR: 1,2,3,4,5,1,3,2,4,9,4,2,1,5,8 
# DF: 1,5,3,8,2,6,1,9,4,2,1,7 

Глядя на подобные ситуации, у меня есть ощущение, что мне нужно использовать комбинацию do.call и cbind или lapply, но я не имею ни малейшего понятия. какие-либо предложения?

+0

Мне нужно использовать в качестве входных данных в функцию '.C' – Stefano

ответ

2
config <- NULL 

config[["secA"]] <- NULL 
config[["secA"]]$VAL <- 0 
config[["secA"]]$ARR <- c(1,2,3,4,5) 
config[["secA"]]$DF <- data.frame(matrix(c(1,5,3,8),2,2)) 

config[["secB"]] <- NULL 
config[["secB"]]$VAL <- 1 
config[["secB"]]$ARR <- c(1,3,2,4,9) 
config[["secB"]]$DF <- data.frame(matrix(c(2,6,1,9),2,2)) 

config[["secC"]] <- NULL 
config[["secC"]]$VAL <- 5 
config[["secC"]]$ARR <- c(4,2,1,5,8) 
config[["secC"]]$DF <- data.frame(matrix(c(4,2,1,7),2,2)) 

sapply(names(config[[1]]), function(x) 
    unname(unlist(sapply(config, `[`, x))), USE.NAMES = TRUE) 

# $VAL 
# [1] 0 1 5 
# 
# $ARR 
# [1] 1 2 3 4 5 1 3 2 4 9 4 2 1 5 8 
# 
# $DF 
# [1] 1 5 3 8 2 6 1 9 4 2 1 7 

Или вы можете использовать функцию this clist

К сожалению, не было никаких других ответов.

(l <- Reduce(clist, config)) 
# $VAL 
# [1] 0 1 5 
# 
# $ARR 
# [1] 1 2 3 4 5 1 3 2 4 9 4 2 1 5 8 
# 
# $DF 
# X1 X2 X1 X2 X1 X2 
# 1 1 3 2 1 4 1 
# 2 5 8 6 9 2 7 

Он объединяет кадры данных и матрицы, так что вам нужно unlist, чтобы получить вектор вы хотите

l$DF <- unname(unlist(l$DF)) 
l 
# $VAL 
# [1] 0 1 5 
# 
# $ARR 
# [1] 1 2 3 4 5 1 3 2 4 9 4 2 1 5 8 
# 
# $DF 
# [1] 1 5 3 8 2 6 1 9 4 2 1 7 

Функция

clist <- function (x, y) { 
    islist <- function(x) inherits(x, 'list') 
    '%||%' <- function(a, b) if (!is.null(a)) a else b 
    get_fun <- function(x, y) 
    switch(class(x %||% y), 
      matrix = cbind, 
      data.frame = function(x, y) 
      do.call('cbind.data.frame', Filter(Negate(is.null), list(x, y))), 
      factor = function(...) unlist(list(...)), c) 

    stopifnot(islist(x), islist(y)) 
    nn <- names(rapply(c(x, y), names, how = 'list')) 
    if (is.null(nn) || any(!nzchar(nn))) 
    stop('All non-NULL list elements should have unique names', domain = NA) 

    nn <- unique(c(names(x), names(y))) 
    z <- setNames(vector('list', length(nn)), nn) 

    for (ii in nn) 
    z[[ii]] <- if (islist(x[[ii]]) && islist(y[[ii]])) 
     Recall(x[[ii]], y[[ii]]) else 
     (get_fun(x[[ii]], y[[ii]]))(x[[ii]], y[[ii]]) 
    z 
} 
+0

ok. определенно из моей лиги ... большое спасибо! Я мог бы оставаться здесь без ведома! – Stefano

+1

@Stefano Я имею в виду, что я уверен, что есть другие способы, но так я бы сделал это, так как я потратил время, чтобы написать это и проверить его, плюс я знал, что он уже существует – rawr

+0

@Stefano. Я добавил один слой, который должен работать очень хорошо, если вам нужны только векторы – rawr

1

Другой подход, с немного меньшим количеством кода.

un_config <- unlist(config) 

un_configNAM <- names(un_config) 

vecNAM <- c("VAL", "ARR", "DF") 

for(n in vecNAM){ 
    assign(n, un_config[grepl(n, un_configNAM)]) 
} 

Это вернет 3 вектора по запросу ОП. Однако, как правило, более выгодно хранить результаты в списке, как предлагает rawr. Конечно, вы можете принять приведенный выше код, чтобы результаты сохранялись в списке.

l <- rep(list(NA), length(vecNAM)) 

i = 1 
for(n in vecNAM){ 
    l[[i]] <- un_config[grepl(n, un_configNAM)] 
    i = i +1 
} 
+0

Я пробовал, но с этим я не получаю массивы – Stefano

+0

Хммм ... Я просто проверял дважды, и это сработало хорошо для меня. Возможно, сначала очистите рабочее пространство? –

+0

Только я не видел редактирования вашего ответа. Я получил его сейчас :) Большое спасибо! – Stefano

Смежные вопросы