1. Трансформация данных
Возник вопрос: как преобразовать данные в R на манер сводных таблиц Excel. Вопрос был решен, но в процессе открыты для себя два полезных пакета, о которых хотелось бы рассказать.
Пакет
reshape2 - позволяет агрегировать данные на манер Excel. На сайте
http://www.r-statistics.com/tag/aggregate/ есть неплохой разбор его возможностей. Основная идея должна быть понятна вот из этой схемы (кликабельна).
Второй пакет --
sqldf. Позволяет писать прямо в коде SQL запросы к данным в синтаксисе SQLite.
Привожу простой код, который решает одну и ту же задачу с использованием двух этих пакетов. Имеются данные по весу кошачьих сердец, кошачьих тушек и пола (Пакет MASS данные cats), Попробуем найти для каждого пола число измерений и средний вес тушки.
Напишем тестовый пример, который бы в цикле 1000 раз пытался решить эту задачу и посчитаем затраченное время.
Возможное решение.
Код:
> library(MASS)
> library(sqldf)
> library(reshape2)
>
> head(cats)
Sex Bwt Hwt
1 F 2.0 7.0
2 F 2.0 7.4
3 F 2.0 9.5
4 F 2.1 7.2
5 F 2.1 7.3
6 F 2.1 7.6
>
> # Первый тест тест. Библиотека sqldf
> x<-Sys.time()
> for(i in 1:1000) z<-sqldf("select Sex,count(*) as cnt,avg(Bwt) as Avg_Bwt from cats group by Sex")
> y<-Sys.time()
> y-x
Time difference of 19.61596 secs
> z
Sex cnt Avg_Bwt
1 F 47 2.359574
2 M 97 2.900000
> # Второй тест. Библиотека reshape 2
> id<-1:nrow(cats)
> mcats<-melt(cbind(id,cats),id=c("id","Sex"))
> x<-Sys.time()
> for(i in 1:1000) {
+ df1<-dcast(subset(mcats,variable == "Bwt"),formula=Sex~variable,length)
+ df2<-dcast(subset(mcats,variable == "Bwt"),formula=Sex~variable,mean)
+ merge(df1,df2,intersect="Sex")
+ }
> y<-Sys.time()
> y-x
Time difference of 12.49125 secs
> z
Sex cnt Avg_Bwt
1 F 47 2.359574
2 M 97 2.900000
Как видно, второй вариант работает гораздо быстрее, но первый проще писать. Так что однозначного выбора нет.
Во втором примере также показано объединение двух таблиц по ключевому полю с использованием команды merge, поскольку команда cast не позволяет агрегировать сразу по двум функциям (может и позволяет, но я не умею).
Такие дела (с).
2. Графы в GNU R
Рассматривая интересные библиотеки в R можно упомянуть о возможности строить графы с помощью библиотеки i
graph.
Простой пример кода. Пытаемся построить граф связей на портале аспирантов (фрагмент).
Код:
library(graph)
# Заполнем фрейм парами данных
left<-rep("Hogfather",16)
right<-c("Alextiger","caty-zharr","Dukar","Ink","IvanSpbRu","Martusya","osmos","saovu","Seta","Uzanka","Vica3","Димитриадис","Дмитрий В.","Домохозяйка","море","Степан Капуста")
left1<-rep("Степан Капуста",2)
right1<-c("Hogfather","Ink")
left<-c(left,left1)
right<-c(right,right1)
left1<-rep("море",10)
right1<-c("agasfer","Alextiger","bugo","fazotron","Hogfather","Ink","IvanSpbRu","Maksimus","Martusya","osmos")
left<-c(left,left1)
right<-c(right,right1)
myData<-data.frame(left,right)
# Формируем и строим граф
g<-graph.data.frame(myData,directed=F)
plot(g,vertex.label.cex=0.8,vertex.label.dist=1,vertex.size=10)
Результат
Нужно или нет, решать вам, но если надо рисовать серьезные графы, то рекомендую сперва глянуть в сторону
graphviz. Очень кошерная и мощная штука.