Подмножество DF с циклом for для запуска каждого подмножества через функцию - PullRequest
1 голос
/ 07 мая 2019

У меня есть набор данных по демографии растений за 5 лет на 10 участках, в общей сложности 37 участков на этих участках. Ниже приведена ссылка на GoogleDoc с некоторыми данными: https://docs.google.com/spreadsheets/d/1VT-dDrTwG8wHBNx7eW4BtXH5wqesnIDwKTdK61xsD0U/edit?usp=sharing

Всего у меня 101 уникальная комбинация.

Мне нужно установить подмножество каждого уникального набора данных, чтобы я мог выполнить каждый через некоторый код. Этот код даст мне один столбец вывода, который мне нужно добавить обратно в исходный фрейм данных, чтобы я мог запустить LM для всего набора данных. Я надеялся написать цикл for, в котором я мог бы поднаборить каждую уникальную комбинацию, выполнить код для каждой из них, а затем добавить выходные данные для каждой модели обратно в исходный набор данных. Все мои попытки написать цикл подмножества не привели даже к простому выводу.

Я создал колонку «SiteTY» с уникальными комбинациями «Сайт», «Трансект», «Год». Таким образом, «PWR 832015» - это сайт PWR Transect 83 год 2015. Я попытался использовать это для циклического прохождения и заполнения пустой матрицы в качестве доказательства концепции.

transect=unique(dat$SiteTY)
ntrans=length(transect)
tmpout=matrix(NA, nrow=ntrans, ncol=2)

for (i in 1:ntrans) {
   df=subset(dat, SiteTY==i)
   tmpout[i,]=(unique(df$SiteTY))
}

Когда я делаю это, я замечаю, что у df нет наблюдений. Если я заменю «i» на известное значение (например, PWR 832015) и выполню каждую строку цикла for отдельно, он будет заполнен правильно. Если я использую is.factor () для i или PWR 832015, оба возвращают FALSE. Этот конкретный код также дает мне ошибку:

Ошибка в [,- (*tmp*,, i, значение = среднее значение (df $ Year)): индекс вне границ

Я могу только предположить, что это происходит, потому что кадр данных пуст. Я прочитал достаточно сообщений SO, чтобы знать, что циклы for сложны, но я пробовал больше итераций, чем я могу вспомнить, чтобы попытаться сделать эту работу за последние 3 года безрезультатно.

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

Ответы [ 2 ]

1 голос
/ 07 мая 2019

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

  1. Использованиеave, если ваша функция ожидает и возвращает один числовой столбец.
  2. Использование by, если ваша функция ожидает фрейм данных и возвращает что-либо.

ave

Возвращает сгруппированный встроенный столбец с повторяющимся значением для каждого члена группы.Ниже with используется в качестве диспетчера контекста, чтобы избежать повторных ссылок dat$.

# BY SITE GROUPING
dat$New_Column <- with(dat, ave(Numeric_Column, Site, FUN=myfunction))

# BY SITE AND TRANSECT GROUPINGS
dat$New_Column <- with(dat, ave(Numeric_Column, Site, Transect, FUN=myfunction))

# BY SITE AND TRANSECT AND YEAR GROUPINGS
dat$New_Column <- with(dat, ave(Numeric_Column, Site, Transect, Year, FUN=myfunction))

by

Возвращает именованный список объектов или любой другойВаша функция возвращается для каждой возможной группировки.Для более чем одной группировки используется tryCatch из-за возможного пустого элемента фрейма данных из всех возможных комбинаций, где ваша моя функция может вернуть ошибку.

# BY SITE GROUPING
obj_list <- by(dat, dat$Site, function(sub) {    
        myfunction(sub)  # RUN ANY OPERATION ON sub DATA FRAME
})

# BY SITE AND TRANSECT GROUPINGS
obj_list <- by(dat, dat[c("Site", "Transect")], function(sub) {    
        tryCatch(myfunction(sub),
                 error = function(e) NULL)
})

# BY SITE AND TRANSECT AND YEAR GROUPINGS
obj_list <- by(dat, dat[c("Site", "Transect", "Year")], function(sub) {    
        tryCatch(myfunction(sub),
                 error = function(e) NULL)
})

# FILTERS OUT ALL NULLs (I.E., NO LENGTH)
obj_list <- Filter(length, obj_list)

# BUILDS SINGLE OUTPUT IF MATRIX OR DATA FRAME
final_obj <- do.call(rbind, obj_list)
0 голосов
/ 07 мая 2019

Вот еще один подход с использованием библиотеки dplyr, в котором я создаю сводный статистический файл data.frame для каждой группы, а затем просто присоединяюсь к нему:

library(dplyr)

# Group by species (site, transect, etc) and summarise
species_summary <- iris %>% 
    group_by(Species) %>% 
    summarise(mean.Sepal.Length = mean(Sepal.Length),
              mean.Sepal.Width = mean(Sepal.Width))

# A data.frame with one row per species, one column per statistic
species_summary

# Join the summary stats back onto the original data
iris_plus <- iris %>% left_join(species_summary, by = "Species")

head(iris_plus)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...