在循环中逐行填充矩阵

时间:2016-05-19 13:50:39

标签: r for-loop matrix

我正在尝试运行循环并填充矩阵。以下是一个示例数据:

#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的行,因为areaarea的所有三个值中最大。同样,对于b,应选择Winter行,因为area是最大值。同样,对于d,应选择Summer行,因为area最大。

因此,最终矩阵(或数据框)应该有一行abcd。但是,当我运行上面的循环时,它只给我d的行而不是其他三行。我认为这与循环的最后一行有关,我指定它填充矩阵results.mat并覆盖先前的选择。但我不确定矩阵,我应该如何按行填充行。

谢谢

2 个答案:

答案 0 :(得分: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 :(得分: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