Как создать список внутри списка, используя элементы из одного вектора, в r

Я пытаюсь создать списки внутри списков, используя один вектор в R.

у меня есть вектор

Conditions = c('A', 'B', 'C', 'D')

и я хочу список, содержащий A, B, C и D (без проблем). Но затем я также хочу, чтобы это были списки, содержащие четыре элемента, названные в соответствии со строками: A vs A, A vs B, ... D vs C, D vs D, в конечном итоге заканчивая списком из четырех списков (A, B, C и D), каждый из которых содержит еще четыре списка (списки «против»), в которые я могу добавить кадры данных.

по сути, я хочу что-то вроде этого:

My list
 |
 |
 |        /- A vs A       /- B vs A      /- C vs A      /- D vs A
 |       /               /              /              /
 |      /- A vs B       /- B vs B      /- C vs B      /- D vs B
 |     /               /              /              /
 ---A-|-------------B-|------------C-|------------D-|                       
       \               \              \              \
        \ - A vs C      \ - B vs C     \ - C vs C     \ - D vs C
         \               \              \              \  
          \- A vs D       \- B vs D      \- C vs D      \- D vs D

Это то, что я пробовал:

Conditions <- c('A', 'B', 'C', 'D')

MyList <- as.list(Conditions) 

for(i in 1:length(MyList)) {
    for(i in 1:length(Conditions)) {
    MyList[i] <- list(paste(MyList[i], 'vs', Conditions[i]))
  }
}

Но это не работает. Например, мой первый элемент просто превращается из A в A vs A vs A vs A vs A.

Обновлено: для большего пояснения я хотел бы,

Список, например,

Letters

Это будет содержать четыре списка,

A, B, C, D

Они, в свою очередь, будут содержать списки, соответствующие их именам:

А: A vs A, A vs B, A vs C, A vs D В: B vs A, B vs B, B vs C, B vs D С: C vs A, C vs B, C vs C, C vs D Д: D vs A, D vs B, D vs C, D vs D

Затем я помещу фрейм данных в каждый «против».

Самый полезный ответ до сих пор был от MrFlick:

lapply(Conditions, function(x) 
  as.list(paste(x, "vs", Conditions)))

Что возвращает:

[[1]]
[[1]][[1]]
[1] "A vs A"

[[1]][[2]]
[1] "A vs B"

[[1]][[3]]
[1] "A vs C"

...

[[4]][[2]]
[1] "D vs B"

[[4]][[3]]
[1] "D vs C"

[[4]][[4]]
[1] "D vs D"

Все, что я хочу, это чтобы список был пуст, а строка использовалась как имя. Для элемента чуть выше, я думаю, это будет выглядеть так:

[[D]][[D vs D]]
    [1] NA        #Data Frame DvsD.Rda to be added here later.

Глядя на другие ответы, мой - единственный, который напоминает нарисованное вами дерево. Это на самом деле то, что вы хотите (сравните с c("A","A","C","D")) или с каждым из условий (c("A","B","C","D"))?

boski 09.04.2019 17:33

Это должно быть A B C D, я ошибся, хотя думал, что уже отредактировал.

Solebay Sharp 09.04.2019 17:35

хорошо, я отредактировал свой ответ соответственно

boski 09.04.2019 17:51
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
3
361
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вот мое решение, посмотрите,

vec <- c("A", "B", "C", "D")

res <- lapply(vec, function(x) {
    out <- expand.grid(x, vec)
    lapply(1:nrow(out), function(y) {
        paste(out[y, 1], " vs ", out[y, 2])
    })
})
str(res)

Результат:

List of 4
 $ :List of 4
  ..$ : chr "A  vs  A"
  ..$ : chr "A  vs  B"
  ..$ : chr "A  vs  C"
  ..$ : chr "A  vs  D"
 $ :List of 4
  ..$ : chr "B  vs  A"
  ..$ : chr "B  vs  B"
  ..$ : chr "B  vs  C"
  ..$ : chr "B  vs  D"
 $ :List of 4
  ..$ : chr "C  vs  A"
  ..$ : chr "C  vs  B"
  ..$ : chr "C  vs  C"
  ..$ : chr "C  vs  D"
 $ :List of 4
  ..$ : chr "D  vs  A"
  ..$ : chr "D  vs  B"
  ..$ : chr "D  vs  C"
  ..$ : chr "D  vs  D"

Извините, я плохо сформулировал свой первоначальный вопрос, не могли бы вы взглянуть на него еще раз?

Solebay Sharp 09.04.2019 22:32

Похоже, ты хочешь

lapply(Conditions, paste, "vs", Conditions)

Это при условии, что векторы в списке в порядке. Если вам нужны списки, то вы можете сделать

lapply(Conditions, function(x) as.list(paste(x, "vs", Conditions)))

Если вам нужно указать имена основного списка, используйте setNames()

Первоначально мне было непонятно, я ищу компоненты «против» также как списки, которые будут заполнены фреймами данных.

Solebay Sharp 09.04.2019 20:30

Я думаю, что на самом деле вы дали мне что-то очень близкое к тому, что я хотел, я просто не могу назвать свои списки.

Solebay Sharp 09.04.2019 20:44

@SolebaySharp Итак, что именно вы хотите, чтобы был конечный объект? Можете ли вы включить желаемый результат в вопрос? Нравится list(A=list("a v a"=list(), "a v b"=list(), ...) и т. д. И как вы планируете туда вставлять data.frames?

MrFlick 09.04.2019 21:00

Это текстовое описание все еще недостаточно точно. Какова реальная структура, которую вы ожидаете? Как бы вы построили его вручную для этого простого примера? Как будет выглядеть dput()?

MrFlick 09.04.2019 21:20

Я не уверен, как построить его вручную, я пытался автоматизировать его, потому что A, B, C и D изменятся. Если бы это были папки, первый путь выглядел бы так: Letters/A/AvsA и в конечном итоге содержал бы фрейм данных AvsA.Rda. Далее будут Letters/A/AvsB/AvsB.Rda и так далее. Затем, когда я рисую позже, я надеюсь, что смогу называть определенные кадры данных по имени, потому что я назвал и организовал их логически.

Solebay Sharp 09.04.2019 21:30

Я думаю, что вы пытаетесь сделать что-то вроде этого:

Conditions <- c('A', 'B', 'C', 'D')

MyList = lapply(Conditions, function(x) list())
names(MyList) = Conditions

for(i in names(MyList)) {
    for(j in 1:length(Conditions)) {
        MyList[[i]][[paste(i, 'vs', Conditions[j])]] = NA #Put NA or the data frame you want.
    }
}

Выход :

$A
$A$`A vs A`
[1] NA

$A$`A vs B`
[1] NA

$A$`A vs C`
[1] NA

$A$`A vs D`
[1] NA


$B
$B$`B vs A`
[1] NA

$B$`B vs B`
[1] NA

$B$`B vs C`
[1] NA

$B$`B vs D`
[1] NA


$C
$C$`C vs A`
[1] NA

$C$`C vs B`
[1] NA

$C$`C vs C`
[1] NA

$C$`C vs D`
[1] NA


$D
$D$`D vs A`
[1] NA

$D$`D vs B`
[1] NA

$D$`D vs C`
[1] NA

$D$`D vs D`
[1] NA

Извините, изначально я не совсем понял, я ищу компоненты «против» также как списки, которые будут заполнены фреймами данных.

Solebay Sharp 09.04.2019 20:35

Как вы могли бы поместить то, что использовалось в качестве строки, в качестве имени для списка? то есть вместо $D [[4]] [1] "D vs D" будет $D $D vs D [1] NA (фрейм данных будет помещен здесь позже).

Solebay Sharp 09.04.2019 22:19

Я также изменил инициализацию MyList

Jet 10.04.2019 12:06
Ответ принят как подходящий

Если ваша логика всегда одна и та же, попробуйте

Conditions = c('A', 'B', 'C', 'D')
L=setNames(as.list(Conditions),Conditions)

L=lapply(L, function(x){
  setNames(vector("list",length(Conditions)),paste0(x," vs ",Conditions))
})

> str(L)
List of 4
 $ A:List of 4
  ..$ A vs A: NULL
  ..$ A vs B: NULL
  ..$ A vs C: NULL
  ..$ A vs D: NULL
 $ B:List of 4
  ..$ B vs A: NULL
  ..$ B vs B: NULL
  ..$ B vs C: NULL
  ..$ B vs D: NULL
 $ C:List of 4
  ..$ C vs A: NULL
  ..$ C vs B: NULL
  ..$ C vs C: NULL
  ..$ C vs D: NULL
 $ D:List of 4
  ..$ D vs A: NULL
  ..$ D vs B: NULL
  ..$ D vs C: NULL
  ..$ D vs D: NULL

Есть ли способ, которым я могу получить $A - A против A, A против B, A против C... и т. д., чтобы я мог заменить строку фреймом данных?

Solebay Sharp 09.04.2019 20:18

Это невероятно близко к тому, что я хочу, но я не могу заставить его соответствовать. не могли бы вы еще раз взглянуть на мой вопрос? Я попытался быть более конкретным.

Solebay Sharp 09.04.2019 22:34

@SolebaySharp это должно ответить на ваш вопрос

boski 10.04.2019 09:27

Другие вопросы по теме