Добавить позиционный индекс в список - PullRequest
1 голос
/ 06 марта 2019

Я хотел бы добавить последовательный элемент в список.Предположим, у меня есть следующий список

lst <- list("A"=list(e1="a",e2="!"), "B"=list(e1="b", e2="@"))
$A
$A$e1
[1] "a"

$A$e2
[1] "!"

$B
$B$e1
[1] "b"

$B$e2
[1] "@"

Я хотел бы добавить e3, который является индексом позиции этого элемента в списке, поэтому по сути я хотел бы, чтобы мой список был:

$A
$A$e1
[1] "a"

$A$e2
[1] "!"

$A$e3
[1] 1

$B
$B$e1
[1] "b"

$B$e2
[1] "@"

$B$e3
[1] 2

Ответы [ 6 ]

2 голосов
/ 06 марта 2019

Другой вариант с использованием Map

Map(function(x, y) c(x, "e3" = y), x = lst, y = seq_along(lst))
#$A
#$A$e1
#[1] "a"

#$A$e2
#[1] "!"

#$A$e3
#[1] 1


#$B
#$B$e1
#[1] "b"

#$B$e2
#[1] "@"

#$B$e3
#[1] 2

Это можно записать еще более кратко, как

Map(c, lst, e3 = seq_along(lst))

Благодаря @ thelatemail

2 голосов
/ 06 марта 2019

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

library("tidyverse")
library("glue")

lst <- list("A"=list(e1="a",e2="!"), "B"=list(e1="b", e2="@"))

# The part
# `setNames(list(.y), glue("e{length(.x) + 1}"))`
# creates a one-element list named accordingly to append to the previous list
map2(lst, seq(lst),
     ~ append(.x, setNames(list(.y), glue("e{length(.x) + 1}") )))
#> $A
#> $A$e1
#> [1] "a"
#> 
#> $A$e2
#> [1] "!"
#> 
#> $A$e3
#> [1] 1
#> 
#> 
#> $B
#> $B$e1
#> [1] "b"
#> 
#> $B$e2
#> [1] "@"
#> 
#> $B$e3
#> [1] 2

# If naming the additional element is not important, then this can simplified to
map2(lst, seq(lst), append)
# or
map2(lst, seq(lst), c)

Создано в 2019-03-06 пакетом представ. (v0.2.1)

2 голосов
/ 06 марта 2019
setNames(lapply(seq_along(lst), function(i){
    temp = lst[[i]]
    temp$e3 = i
    temp
}), names(lst))
#$`A`
#$`A`$`e1`
#[1] "a"

#$`A`$e2
#[1] "!"

#$`A`$e3
#[1] 1


#$B
#$B$`e1`
#[1] "b"

#$B$e2
#[1] "@"

#$B$e3
#[1] 2
1 голос
/ 07 марта 2019

Также можно использовать петлю for

for(i in seq_along(lst)) lst[[i]]$e3 <- i
1 голос
/ 06 марта 2019

Мы можем выполнить цикл по длине lst с помощью lapply, добавив этот последовательный индекс к каждому элементу.

lst2 <- lapply(seq_along(lst), function(i) {
    df <- lst[[i]]
    df$e3 <- i
    return(df)
})
names(lst2) <- names(lst) # Preserve names from lst

Или, если вы не боитесь модификации на месте:

lapply(seq_along(lst), function(i) {
    lst[[i]]$e3 <<- i
})

Оба выдают одинаковый вывод:

$A
$A$e1
[1] "a"
$A$e2
[1] "!"
$A$e3
[1] 1


$B
$B$e1
[1] "b"
$B$e2
[1] "@"
$B$e3
[1] 2
1 голос
/ 06 марта 2019

Если я правильно понял, что вы хотите добавить 3-й элемент в каждый вложенный список, который содержит индекс этого списка в его родительском списке. Это работает:

library(rlist)    
lst <- list("A"=list(e1="a",e2="!"), "B"=list(e1="b", e2="@"))
for(i in seq(1:length(lst))){
  lst[[i]] <- list.append(lst[[i]],e3=i)  
}
lst
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...