Как разбить кадр данных по строкам, а затем обработать блоки?
У меня есть кадр данных с несколькими столбцами, один из которых является фактором, называемым "сайтом". Как я могу разделить фрейм данных на блоки строк с уникальным значением "сайт", а затем обработать каждый блок с помощью функции? Данные выглядят следующим образом:
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
vs peak
для каждого сайта.
Ответы
Ответ 1
Другой вариант - использовать функцию ddply
из библиотеки ggplot2
. Но вы упоминаете, что в основном хотите построить график пиковых и qplot
, поэтому вы также можете просто использовать 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]()
С другой стороны, мне нравится решение Дэвида Смита, которое позволяет применять эту функцию на нескольких процессорах.
Ответ 2
Вы можете использовать isplit
(из пакета "итераторы" ), чтобы создать объект-итератор, который перебирает блоки, определенные столбцом 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
Ответ 3
Мне кажется, что обычный старый split()
имеет метод для data.frames, так что split(data,data$site)
создаст список блоков. Затем вы можете использовать этот список, используя sapply
/lapply
/for
.
split()
также хорош из-за unsplit()
, который создаст вектор такой же длины, что и исходные данные и в правильном порядке.
Ответ 4
Вот что я буду делать, хотя, похоже, вы, ребята, справились с библиотечными функциями.
for(i in 1:length(unique(data$site))){
constrainedData = data[data$site==data$site[i]];
doSomething(constrainedData);
}
Этот тип кода более прямой и может быть менее эффективным, но я предпочитаю читать, что он делает, чем изучать новую библиотечную функцию для одной и той же вещи. делает это чувство более гибким, но, честно говоря, это именно то, как я понял это как новичок.
Ответ 5
Есть две удобные встроенные функции для работы с такими ситуациями.? aggregate и? by. В этом случае, поскольку вы хотите построить график и не возвращаете скаляр, используйте()
data <- read.table("example.txt",header=TRUE)
by(data[, c('year', 'peak')], data$site, plot)
На выходе написано NULL
, потому что этот сюжет возвращается. Возможно, вы захотите установить графическое устройство в pdf, чтобы захватить весь вывод.
Ответ 6
Также очень легко сгенерировать ваши графики с помощью пакета решетки:
library(lattice)
xyplot(year~peak | site, data)
Ответ 7
Вы можете использовать функцию split
Если вы открыли свои данные как:
data <- read.table('your_data.txt', header=T)
blocks <- split(data, data$site)
После этого блоки содержат данные из каждого блока, к которым вы можете получить доступ, как другие data.frame:
plot(blocks$ALBEN$year, blocks$ALBEN$peak)
И так далее для каждого сюжета.