Вложенность нескольких списков с split(), R
Учитывая набор данных с несколькими уникальными элементами в столбце, я хотел бы разбить эти уникальные элементы на новые кадры данных, но вложил их на один уровень вниз. По сути, добавив дополнительный уровень к split()
команда.
Например (используя встроенный iris
Таблица в качестве примера:
iris
mylist <- split(iris, iris$Species)
производит список, mylist
, который содержит 3 подсписка, setosa
, versicolor
, virginica
,
mylist[["setosa"]]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
Но на самом деле я хотел бы вложить эту таблицу данных в список под названием results
НО сохранить имя списка верхнего уровня как setosa
, Такой что:
mylist$setosa["results"]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
Я мог бы сделать это с помощью ручных манипуляций, но я бы хотел, чтобы это запускалось автоматически. Я безуспешно пытался mapply
mapply(function(names, df)
names <- split(df, df[["Species"]]),
unique(iris$Species), iris)
Любой совет? Также с удовольствием использовать tidyr
пакет, если это делает вещи проще...
2 ответа
Рассматривать by
(объектно-ориентированная оболочка tapply
), очень похоже на split
но позволяет запускать функцию для каждого подмножества. Часто многие пользователи запускаются split
+ lapply
л оба могут заменить by
:
mylist <- by(iris, iris$Species, function(sub) list(results=sub), simplify = FALSE)
head(mylist$setosa$results)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 3.5 1.4 0.2 setosa
# 2 4.9 3.0 1.4 0.2 setosa
# 3 4.7 3.2 1.3 0.2 setosa
# 4 4.6 3.1 1.5 0.2 setosa
# 5 5.0 3.6 1.4 0.2 setosa
# 6 5.4 3.9 1.7 0.4 setosa
head(mylist$versicolor$results)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 51 7.0 3.2 4.7 1.4 versicolor
# 52 6.4 3.2 4.5 1.5 versicolor
# 53 6.9 3.1 4.9 1.5 versicolor
# 54 5.5 2.3 4.0 1.3 versicolor
# 55 6.5 2.8 4.6 1.5 versicolor
# 56 5.7 2.8 4.5 1.3 versicolor
head(mylist$virginica$results)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 101 6.3 3.3 6.0 2.5 virginica
# 102 5.8 2.7 5.1 1.9 virginica
# 103 7.1 3.0 5.9 2.1 virginica
# 104 6.3 2.9 5.6 1.8 virginica
# 105 6.5 3.0 5.8 2.2 virginica
# 106 7.6 3.0 6.6 2.1 virginica
setNames
в lapply
сохранит названия списка, через который вы перебираете
iris
mylist <- split(iris, iris$Species)
mylist2 <- lapply(setNames(names(mylist), names(mylist)), function(x){
list(results = mylist[[x]])
})