Как разделить фрейм данных по строкам, а затем обработать блоки?

StackOverflow https://stackoverflow.com/questions/1395191

  •  21-09-2019
  •  | 
  •  

Вопрос

У меня есть фрейм данных с несколькими столбцами, один из которых является фактором под названием "сайт".Как я могу разделить фрейм данных на блоки строк, каждый из которых имеет уникальное значение "site", а затем обработать каждый блок с помощью функции?Данные выглядят следующим образом:

site year peak
ALBEN 5 101529.6
ALBEN 10 117483.4
ALBEN 20 132960.9
ALBEN 50 153251.2
ALBEN 100 168647.8
ALBEN 200 184153.6
ALBEN 500 204866.5
ALDER 5 6561.3
ALDER 10 7897.1
ALDER 20 9208.1
ALDER 50 10949.3
ALDER 100 12287.6
ALDER 200 13650.2
ALDER 500 15493.6
AMERI 5 43656.5
AMERI 10 51475.3
AMERI 20 58854.4
AMERI 50 68233.3
AMERI 100 75135.9
AMERI 200 81908.3

и я хочу создать сюжет о year против peak для каждого сайта.

Это было полезно?

Решение

Другой вариант - использовать ddply функция из ggplot2 библиотека.Но вы упомянули, что в основном хотите снять сюжет "пик противгод, так что вы также могли бы просто использовать qplot:

A <- read.table("example.txt",header=TRUE)
library(ggplot2)
qplot(peak,year,data=A,colour=site,geom="line",group=site)
ggsave("peak-year-comparison.png")

alt text

С другой стороны, мне действительно нравится решение Дэвида Смита, которое позволяет запускать применение функции на нескольких процессорах.

Другие советы

Вы можете использовать isplit (из пакета "iterators") для создания объекта iterator, который перебирает блоки, определенные site колонна:

require(iterators)
site.data <- read.table("isplit-data.txt",header=T) 
sites <- isplit(site.data,site.data$site)

Тогда вы можете использовать foreach (из пакета "foreach") для создания графика внутри каждого блока:

require(foreach)
foreach(site=sites) %dopar% {
 pdf(paste(site$key[[1]],".pdf",sep=""))
 plot(site$value$year,site$value$peak,main=site$key[[1]])
 dev.off()
}

В качестве бонуса, если у вас есть многопроцессорная машина и вызываете registerDoMC() во-первых (из пакета "doMC") циклы будут выполняться параллельно, что ускорит процесс.Более подробная информация в этом сообщении в блоге Revolutions: Блок-обработка фрейма данных с помощью isplit

Кажется, я припоминаю это простое старое split() имеет метод для data.frames, так что split(data,data$site) создало бы список блоков.Затем вы могли бы оперировать этим списком, используя sapply/lapply/for.

split() это также приятно, потому что unsplit(), который создаст вектор той же длины, что и исходные данные, и в правильном порядке.

Вот что бы я сделал, хотя, похоже, у вас, ребята, это обрабатывается библиотечными функциями.

for(i in 1:length(unique(data$site))){
  constrainedData = data[data$site==data$site[i]];
  doSomething(constrainedData);
}

Этот вид кода более прямой и может быть менее эффективным, но я предпочитаю иметь возможность читать, что он делает, чем изучать какую-то новую библиотечную функцию для того же самого.это тоже делает это более гибким, но, честно говоря, это именно то, как я понял это, будучи новичком.

Есть две удобные встроенные функции для работы с подобными ситуациями.?совокупный и ?by.В этом случае, поскольку вам нужен график и вы не возвращаете скаляр, используйте by()

data <- read.table("example.txt",header=TRUE)

by(data[, c('year', 'peak')], data$site, plot)

На выходе говорится NULL потому что это то, что возвращает plot.Возможно, вы захотите настроить графическое устройство на формат pdf, чтобы записывать все выходные данные.

Также очень легко создавать ваши графики с помощью пакета lattice:

library(lattice)
xyplot(year~peak | site, data)

Вы могли бы использовать split функция Если вы открыли свои данные как:

data <- read.table('your_data.txt', header=T)
blocks <- split(data, data$site)

После этого blocks содержит данные из каждого блока, к которым вы можете получить доступ как к другим данным.frame:

plot(blocks$ALBEN$year, blocks$ALBEN$peak)

И так далее для каждого сюжета.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top