Повторное применение функции ко многим предметам - PullRequest
2 голосов
/ 06 мая 2011

У меня есть фрейм данных следующим образом:

> mydata
date  station  treatment  subject   par
A       a         0         R1      1.3    
A       a         0         R1      1.4    
A       a         1         R2      1.4   
A       a         1         R2      1.1    
A       b         0         R1      1.5    
A       b         0         R1      1.8     
A       b         1         R2      2.5     
A       b         1         R2      9.5    
B       a         0         R1      0.3    
B       a         0         R1      8.2    
B       a         1         R2      7.3    
B       a         1         R2      0.2    
B       b         0         R1      9.4    
B       b         0         R1      3.2    
B       b         1         R2      3.5    
B       b         1         R2      2.4 
....

, где:

date - коэффициент с 2 уровнями A / B;station - фактор с 2 уровнями a / b;treatment - фактор с 2 уровнями 0/1;

subject - это копии R1-R20, назначенные для обработки (от 10 до treatment 0 и от 10 до обработки 1);

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

Что мне нужно сделать, это: разделить паритет на 10 равных ячеек и посчитать число в каждом ящике.Это должно быть сделано в подмножествах mydata, определяемых комбинацией станции даты и темы.Окончательный результат должен выглядеть следующим образом:

> myres
    date  station  treatment  bin.centre  freq
    A       a         0         1.2        4 
    A       a         0         1.3        3    
    A       a         0         1.4        2 
    A       a         0         1.5        1    
    A       a         1         1.2        4    
    A       a         1         1.3        3    
    A       a         1         1.4        2     
    A       a         1         1.5        1    
    B       b         0         2.3        5   
    B       b         0         2.4        4    
    B       b         0         2.5        3    
    B       b         0         2.6        2   
    B       b         1         2.3        5   
    B       b         1         2.4        4   
    B       b         1         2.5        3   
    B       b         1         2.6        2
    ....

: вот что я сделал до сих пор:

#define the number of bins
num.bins<-10

#define the width of each bins
bin.width<-(max(par)-min(par))/num.bins

#define the lower and upper boundaries of each bins
bins<-seq(from=min(par), to=max(par), by=bin.width)

#define the centre of each bins
bin.centre<-c(seq(min(bins)+bin.width/2,max(bins)-bin.width/2,by=bin.width))

#create a vector to store the frequency in each bins

  freq<-numeric(length(length(bins-1)))

 # this is the loop that counts the frequency of particles between the lower and upper boundaries
 of each bins and store the result in freq

 for(i in 1:10){
    freq[i]<-length(which(par>=bins[i] &
    par<bins[i+1]))
     }

 #create the data frame with the results
 res<-data.frame(bin.centre,res)

Мой первый подход заключался в том, чтобы вручную задавать подмножество mydata., используя subset(), для каждой комбинации предметной станции и даты и примените вышеуказанную последовательность команд для каждого подмножества, затем создайте окончательный кадр данных, объединяющий каждый отдельный res, используя rbind(), но эта процедура была очень запутанной и предметнойраспространению ошибок.То, что я хотел бы сделать, это автоматизировать описанную выше процедуру, чтобы она вычисляла распределение частот для каждого субъекта.Моя интуиция заключается в том, что лучший способ сделать это - создать функцию для оценки распределения частиц, а затем применить ее к каждому объекту с помощью цикла for.Однако я не уверен, как это сделать.Будем очень благодарны за любые предложения.

спасибо matteo.

1 Ответ

4 голосов
/ 06 мая 2011

Вы можете сделать это в несколько шагов, используя функциональность пакета plyr.Это позволяет вам разбить ваши данные на нужные блоки, применить статистику к каждому блоку и объединить результаты.

Сначала я настроил несколько фиктивных данных:

set.seed(1)
n <- 100
dat <- data.frame(
    date=sample(LETTERS[1:2], n, replace=TRUE),
    station=sample(letters[1:2], n, replace=TRUE),
    treatment=sample(0:1, n, replace=TRUE),
    subject=paste("R", sample(1:2, n, replace=TRUE), sep=""),
    par=runif(n, 0, 5)
)
head(dat)

  date station treatment subject       par
1    A       b         0      R2 3.2943880
2    A       a         0      R1 0.9253498
3    B       a         1      R1 4.7718907
4    B       b         0      R1 4.4892425
5    A       b         0      R1 4.7184853
6    B       a         1      R2 3.6184538

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

dat$bin <- cut(dat$par, breaks=10)

Теперь самое интересное.Загрузите пакет plyr и используйте функцию ddply для разделения, применения и объединения.Поскольку вам нужен подсчет частоты, мы можем использовать функцию length, чтобы подсчитать, сколько раз каждая реплика появлялась в этой корзине:

library(plyr)
res <- ddply(dat, .(date, station, treatment, bin), 
  summarise, freq=length(treatment))
head(res)

  date station treatment             bin freq
1    A       a         0 (0.00422,0.501]    1
2    A       a         0   (0.501,0.998]    2
3    A       a         0      (1.5,1.99]    4
4    A       a         0     (1.99,2.49]    2
5    A       a         0     (2.49,2.99]    2
6    A       a         0     (2.99,3.48]    1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...