R - Выполнить те же операции для многих наборов данных - PullRequest
1 голос
/ 09 марта 2020

Извиняюсь, если это повторяющийся вопрос, если ответ где-то существует, я был бы признателен за указание на него. Вот сокращенный пример:

x1 = sample(x = c("A", "B", "C"), size = 50, replace = TRUE)
x2 = sample(x = c(5, 10, 27), size = 50, replace = TRUE)
y = rnorm(50, mean=0)

dat = as.data.frame(cbind(y, x1, x2))
dat$x2 = as.numeric(dat$x2)
dat$y = as.numeric(dat$y)

> head(dat)
   y x1 x2
1  9  C  2
2  7  C  2
3  8  B  1
4 21  A  2
5 48  A  1
6 19  A  3

Я хочу установить поднабор этого набора данных для каждого уровня x1, поэтому я получаю 3 новых набора данных для каждого уровня фактора x1. Я могу сделать это следующим образом:

#A
dat.A = dat[which(dat$x1== "A"),,drop=T]
dat.A$x1 = factor(dat.A$x1)

#B
dat.B = dat[which(dat$x1== "B"),,drop=T]
dat.B$x1 = factor(dat.B$x1)

#C
dat.C = dat[which(dat$x1== "C"),,drop=T]
dat.C$x1 = factor(dat.C$x1)

Это несколько утомительно, так как мои реальные данные имеют 7 уровней фактора интереса, поэтому я должен повторить код 7 раз. Получив каждый новый фрейм данных в своей глобальной среде, я хочу выполнить несколько функций для каждого (построение графиков, создание таблиц, подбор линейных моделей). Вот простой пример:

#same plot for each dataset
A.plot = plot(dat.A$y, dat.A$x2)
B.plot = plot(dat.B$y, dat.B$x2)
C.plot = plot(dat.C$y, dat.C$x2)

#same models for each dataset
mod.A = lm(y ~ x2, data = dat.A)
summary(mod.A)
mod.B = lm(y ~ x2, data = dat.B)
summary(mod.B)
mod.C = lm(y ~ x2, data = dat.C)
summary(mod.C)

Это много копирования и вставки. Есть ли способ, которым я могу написать одну строку кода для каждой вещи, которую я хочу сделать, и l oop для каждого набора данных? Что-то вроде ниже, что я знаю, это неправильно, но это то, что я пытаюсь сделать:

for (i in datasets) {
  [i].plot = plot(dat.[i]$y, dat.[i]$x2)
  mod.[i] = lm(y ~ x2, data = dat[i])
}

Ответы [ 2 ]

1 голос
/ 09 марта 2020

Мы можем сделать split в list фреймов данных, а затем l oop над list с lapply

lst1 <- split(dat, dat$x1)
lst2 <- lapply(lst1, function(dat) {
             plt <- plot(dat$y, dat$x2)
             model <- lm(y ~ x2, data = dat)
             list(plt, model)
          })
0 голосов
/ 09 марта 2020

Для полноты картины вот как я бы сделал это в tidyverse, создав два списка: один с графиками и один с моделями.

library(dplyr)
library(ggplot2)

model_list <- dat %>%
  group_by(x1) %>%
  group_map( ~ lm(y ~ x2, data = .x))

plot_list <- dat %>%
  group_by(x1) %>%
  group_map( ~ ggplot(.x, aes(x2, y)) + geom_point())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...