Генерация нескольких наборов данных и применение функции и вывод нескольких наборов данных - PullRequest
4 голосов
/ 04 сентября 2011

Вот моя проблема, мне просто тяжело ...

Я хочу создать несколько наборов данных, затем применить функцию к этим наборам данных и вывести соответствующие выходные данные в одном или нескольких наборах данных (все, что возможно) ...

Мой пример, хотя мне нужно сгенерировать большое количество переменных и наборов данных

seed <- round(runif(10)*1000000)

datagen <- function(x){
set.seed(x)
var <- rep(1:3, c(rep(3, 3)))
yvar <- rnorm(length(var), 50, 10)
matrix <- matrix(sample(1:10, c(10*length(var)), replace = TRUE), ncol = 10)
mydata <- data.frame(var, yvar, matrix)
}

gdt <- lapply (seed,  datagen) 

# resulting list (I believe is correct term) has 10 dataframes: 
# gdt[1] .......to gdt[10]

# my function, this will perform anova in every component data frames and 
#output probability coefficients...  
anovp <- function(x){
          ind <- 3:ncol(x) 
          out <- lm(gdt[x]$yvar ~ gdt[x][, ind[ind]])
          pval <- out$coefficients[,4][2]
          pval <- do.call(rbind,pval) 
         }

plist <- lapply (gdt,  anovp) 

Error in gdt[x] : invalid subscript type 'list'

Это не работает, я пробовал разные варианты. Но не смог разобраться ... наконец решил заморачиваться с экспертами, простите за это ...

Мои вопросы:

(1) Возможно ли справиться с такой ситуацией подобным образом или есть другие альтернативы для обработки таких созданных множественных наборов данных?

(2) Если это правильный путь, как я могу это сделать?

Спасибо за внимание, и я буду признателен за вашу помощь ...

1 Ответ

7 голосов
/ 04 сентября 2011

У вас есть основная идея: вы должны создать список фреймов данных, а затем использовать lapply, чтобы применить функцию к каждому элементу списка. К сожалению, в вашем коде есть несколько странностей.

Нет смысла случайным образом генерировать начальное число, а затем устанавливать его. Вам нужно всего лишь использовать set.seed для того, чтобы сделать воспроизводимые случайные числа. Отрежь линии

seed <- round(runif(10)*1000000)

и, возможно,

set.seed(x)

rep(1:3, c(rep(3, 3))) совпадает с rep(1:3, each = 3).


Не вызывайте ваши переменные var или matrix, , поскольку они будут маскировать имена этих функций. , поскольку это сбивает с толку.


3:ncol(x) опасно. Если x имеет менее 3 столбцов, он не делает то, что вы думаете.


... а теперь проблема, которую вы на самом деле хотели решить.

Проблема в строке out <- lm(gdt[x]$yvar ~ gdt[x][, ind[ind]]).

lapply передает фреймы данных в anovp, а не указывает, поэтому x является фреймом данных в gdt[x]. Который выдает ошибку.


Еще одна вещь. Когда вы переписываете эту строку, обратите внимание, что lm принимает аргумент данных, поэтому вам не нужно делать такие вещи, как gdt$some_column; Вы можете просто ссылаться на some_column напрямую.


РЕДАКТИРОВАТЬ: Дальнейшие советы.

Вы, кажется, всегда используете формулу yvar ~ X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10. Так как каждый раз одно и то же, создайте его перед вызовом lapply.

independent_vars <- paste(colnames(gdt[[1]])[-1:-2], collapse = " + ")
model_formula <- formula(paste("yvar", independent_vars, sep = " ~ "))

Возможно, я бы не стал беспокоиться о функции anovp. Просто сделай

models <- lapply(gdt, function(data) lm(model_formula, data))

Затем включите дополнительный вызов lapply, чтобы поиграть с коэффициентами, если необходимо. Следующая строка копирует ваш код anovp, но не будет работать, потому что model$coefficients - это вектор (поэтому размеры не верны). Отрегулируйте, чтобы получить бит, который вы на самом деле хотите.

coeffs <- lapply(models, function(model) do.call(rbind, model$coefficients[,4][2]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...