2016-05-19 2 views
0

Я пытаюсь запустить цикл и заполнить матрицу. Вот образец данные:заполнить матрицу по строке в цикле

#generate sample data 
reg<-rep(c("a","b","c","d"),each=3) 
year<-rep(c(2005:2008),each=3) 
sea<-rep(c("Winter","Summer","Autumn"),4) 
set.seed(1) 
area<-runif(12) 
prod<-runif(12) 
yld<-runif(12) 
dat<-data.frame(reg,year,sea,area,prod,yld) 
dat$reg<-as.character(dat$reg) 
dat$sea<-as.character(dat$sea) 
str(dat) 

#create an empty matrix to store my results 
results.mat <- matrix(0, ncol = 6, nrow = NROW(unique(dat$reg))) 

#create a loop 
for (j in unique(sort(dat$reg))){ 
reg<-dat[dat$reg==j,] 
for (k in unique(sort(reg$year))){ 
    year<-reg[reg$year==k,] 
    results.mat<-year[year$area==max(year$area),] 
}} 
results.mat 

То, что я пытаюсь сделать, это для каждого reg и для каждого year, я хочу, чтобы извлечь эту строку, где area максимально. Это означает, что для a следует выбрать строку с Autumn, так как area является максимальным среди всех трех значений area. Аналогично, для b, строка с Winter должна быть выбрана с area является максимальной. Аналогично, для d, строка с Summer должна быть выбрана с area является максимальной.

Поэтому окончательная матрица (или dataframe) должны иметь одну строку для a, b, c, d. Однако, когда я запускаю свой цикл выше, он дает мне только строку для d, а не для остальных трех. Я думаю, что это связано с последней строкой цикла, где я указываю, что она заполняет матрицу results.mat и перезаписывает предыдущий выбор. Но я не уверен в матрице, как я должен заполнять строки по строкам.

Благодаря

+0

Матрицы и data.frames различны. Если вы хотите выбрать строки data.frame, результатом будет/должен быть также data.frame (как в ответе ниже). – Frank

+0

Один параметр в базе R: 'dat [as.logical (ave (dat $ area, dat $ reg, dat $ year, FUN = function (x) x == max (x), drop = TRUE)),]' – nicola

ответ

2

Раствор с использованием пакета data.table выглядит следующим образом:

library(data.table) 
setDT(dat) 

# subset data according to max area by reg-year 
dat[, .SD[which.max(area),], by=c("reg", "year")] 
1

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

library(dplyr); 
dat %>% group_by(reg, year) %>% filter(area == max(area)) 

Source: local data frame [4 x 6] 
Groups: reg, year [4] 

    reg year sea  area  prod  yld 
    (chr) (int) (chr)  (dbl)  (dbl)  (dbl) 
1  a 2005 Autumn 0.5728534 0.7698414 0.01339033 
2  b 2006 Winter 0.9082078 0.4976992 0.38238796 
3  c 2007 Winter 0.9446753 0.3800352 0.48208012 
4  d 2008 Summer 0.2059746 0.6516738 0.82737332 
+0

Другим стандартным вариантом является '%>% slice (which.max (area))' вместо 'filter'. – Frank

Смежные вопросы