Как создать новый список, содержащий каждый отдельный столбец матрицы из старого списка в R? - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь создать новый список, который содержит каждый отдельный столбец матрицы из старого списка.Например:

var_names <- c('a', 'b', 'c', 'd')
var_combi <- list()
for(i in 1:length(var_names)) {var_combi[[i]] <- combn(var_names[1:length(var_names)],i)}
c(var_combi)

Затем я получил список объектов, как показано ниже.Каждый перечисленный элемент представляет собой матрицу:

[[1]]
     [,1] [,2] [,3] [,4]
[1,] "a"  "b"  "c"  "d" 

[[2]]
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,] "a"  "a"  "a"  "b"  "b"  "c" 
[2,] "b"  "c"  "d"  "c"  "d"  "d" 

[[3]]
     [,1] [,2] [,3] [,4]
[1,] "a"  "a"  "a"  "b" 
[2,] "b"  "b"  "c"  "c" 
[3,] "c"  "d"  "d"  "d" 

[[4]]
     [,1]
[1,] "a" 
[2,] "b" 
[3,] "c" 
[4,] "d" 

Я хочу создать новый список new_list, например, приведенный ниже, например,

[[1]]
[1] "a"

[[2]] 
[1] "b"

[[3]] 
[1] "c" 

[[4]]
[1] "d" 

[[5]]
[1]  "a" "b"

[[6]]
[1]  "a" "c"

, чтобы я мог зациклить их или использовать lapply, чтобы выбрать эти переменные из моего набора данных mydata, используя mydata[names(mydata) %in% new_list[[i]]].

Сейчас я изо всех сил пытаюсь создать new_list и не могу найти правильное решение для этого (я попытался unlist,c и append).Если мне нужно использовать цикл for, как мне перебрать список и перечисленные здесь столбцы матрицы?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Вот простой подход с использованием base R:

unlist(lapply(seq_along(var_names), function(x) {
    combn(var_names, x, simplify = FALSE)
}), recursive = FALSE)

[[1]]
[1] "a"

[[2]]
[1] "b"

[[3]]
[1] "c"

[[4]]
[1] "d"

[[5]]
[1] "a" "b"

[[6]]
[1] "a" "c"
.
.    ### 9 more elements
.

Это незначительная модификация кода ОП.Здесь мы используем lapply вместо цикла for и также устанавливаем simplify = FALSE в combn (по умолчанию simplify = TRUE).Этот аргумент, если FALSE, оставит результат в запрошенном формате списка.Вы также заметите, что мы используем unlist с rescursive = FALSE, который прекращает перечисление после первого уровня.

Если вы действительно хотите краткости, мы можем использовать функцию powerset из библиотеки rje.Мы должны помнить, что нам нужно удалить первый элемент, который эквивалентен пустому набору:

rje::powerSet(letters[1:4])[-1]

[[1]]
[1] "a"

[[2]]
[1] "b"

[[3]]
[1] "a" "b"

[[4]]
[1] "c"

[[5]]
[1] "a" "c"

[[6]]
[1] "b" "c"

[[7]]
[1] "a" "b" "c"

[[8]]
[1] "d"

[[9]]
[1] "a" "d"

[[10]]
[1] "b" "d"

[[11]]
[1] "a" "b" "d"

[[12]]
[1] "c" "d"

[[13]]
[1] "a" "c" "d"

[[14]]
[1] "b" "c" "d"

[[15]]
[1] "a" "b" "c" "d"
0 голосов
/ 09 ноября 2018

Если вы не возражаете против использования функционального подхода вместо цикла, это должно сработать:

library(dplyr)
library(purrr)

c(var_combi) %>%
  map(t) %>%
  map(~ split(., 1:nrow(.))) %>%
  unlist(recursive = F)
...