比较R中两个相等长度data.frames的相同位置的值

时间:2015-08-17 11:57:04

标签: r

我是R的新手,所以我不确定是否已经问过类似的问题,但是搜索并没有给我答案。

有两种data.frames,具有相同的列数(321)和行(281),按纬度和经度排序。 DF1(" Laender")包含德语状态作为字符。它看起来像这样:

lat\lon   ...  8.70         8.75         8.80    ...
...        
51.30          Hessen       Hessen       Hessen
51.25          NRWestfalen  Hessen       Hessen
51.20          NRWestfalen  NRWestfalen  Hessen
51.15          NRWestfalen  Hessen       Hessen
...

DF2(" df")包含以相同方式排序的值。我一年中的每个小时都有不同的DF2,需要得到每个德国的平均值。它确实以下列方式工作:

Laender <- read.csv("path/file.csv", row.names = 1, check.names = F)
df <- read.csv("path/file1.csv", row.names = 1, check.names = F)

#  XXtot <- 0 creating the needed variables

for(i in 1:321){
  for(j in 1:281){
    BYtot <- ifelse(Laender[i,j]=="Bayern", BYtot + df[i,j], BYtot)
    SDtot <- ifelse(Laender[i,j]=="Saarland", SDtot + df[i,j], SDtot)
    BWtot <- ifelse(Laender[i,j]=="BadenW", BWtot + df[i,j], BWtot)
    STtot <- ifelse(Laender[i,j]=="SAnhalt", STtot + df[i,j], STtot)
    SNtot <- ifelse(Laender[i,j]=="Sachsen", SNtot + df[i,j], SNtot)
    MVtot <- ifelse(Laender[i,j]=="MVorpommern", MVtot + df[i,j], MVtot)
    NRWtot <- ifelse(Laender[i,j]=="NRWestfalen", NRWtot + df[i,j], NRWtot)
    BEtot <- ifelse(Laender[i,j]=="Berlin", BEtot + df[i,j], BEtot)
    HHtot <- ifelse(Laender[i,j]=="Hamburg", HHtot + df[i,j], HHtot)
    HBtot <- ifelse(Laender[i,j]=="Bremen", HBtot + df[i,j], HBtot)
    SHtot <- ifelse(Laender[i,j]=="SHolstein", SHtot + df[i,j], SHtot)
    NStot <- ifelse(Laender[i,j]=="Niedersachsen", NStot + df[i,j], NStot)
    HEtot <- ifelse(Laender[i,j]=="Hessen", HEtot + df[i,j], HEtot)
    THtot <- ifelse(Laender[i,j]=="Thueringen", THtot + df[i,j], THtot)
    RPtot <- ifelse(Laender[i,j]=="RPfalz", RPtot + df[i,j], RPtot)
    BRtot <- ifelse(Laender[i,j]=="Brandenburg", BRtot + df[i,j], BRtot)
  }
}

这将为我提供每个德国州的总价值,我可以计算此后的平均值,但由于我必须对所有8760版本的DF2执行此程序,所以需要的时间太长。

我希望有一种更容易,更快捷的方法。

1 个答案:

答案 0 :(得分:0)

这是tapply()的目的。这是一个使用随机数据的演示(因此纬度/经度位置和状态名称不符合现实):

states <- c('Bayern','Saarland','BadenW','SAnhalt','Sachsen','MVorpommern','NRWestfalen','Berlin','Hamburg','Bremen','SHolstein','Niedersachsen','Hessen','Thueringen','RPfalz','Brandenburg');
lats <- seq(51.30,by=-0.05,len=281);
lons <- seq(8.70,by=0.05,len=321);
set.seed(1);
Laender <- as.data.frame(matrix(sample(states,length(lats)*length(lons),replace=T),length(lats),dimnames=list(sprintf('%.2f',lats),sprintf('%.2f',lons))));
df <- as.data.frame(matrix(pmax(0,round(rnorm(length(lats)*length(lons),5,20))),length(lats),dimnames=list(sprintf('%.2f',lats),sprintf('%.2f',lons))));
Laender[1:6,1:6];
##              8.70        8.75          8.80          8.85        8.90     8.95
## 51.30     Sachsen     Hamburg   MVorpommern        Berlin      Hessen   Hessen
## 51.25 MVorpommern      RPfalz Niedersachsen        Berlin      RPfalz   Berlin
## 51.20      Bremen MVorpommern        RPfalz   NRWestfalen     Sachsen   Bayern
## 51.15      RPfalz      Bayern Niedersachsen        Bayern      Berlin   BadenW
## 51.10     SAnhalt      BadenW       SAnhalt     SHolstein     Sachsen   BadenW
## 51.05      RPfalz MVorpommern     SHolstein Niedersachsen MVorpommern Saarland
df[1:6,1:6];
##       8.70 8.75 8.80 8.85 8.90 8.95
## 51.30   16    1    0   14    0    5
## 51.25   24    0   11    0   27    0
## 51.20   15    0    0   13    0   25
## 51.15    0   21    0   21    2    0
## 51.10   30    0    0   15    0    0
## 51.05    0    0    0   31    0    0
tapply(as.matrix(df),as.matrix(Laender),mean);
##        BadenW        Bayern        Berlin   Brandenburg        Bremen
##      10.35327      10.30455      10.80498      11.09401      10.57423
##       Hamburg        Hessen   MVorpommern Niedersachsen   NRWestfalen
##      11.05088      10.55788      10.66969      10.90239      11.09304
##        RPfalz      Saarland       Sachsen       SAnhalt     SHolstein
##      10.54924      10.48975      10.87170      10.49251      10.51719
##    Thueringen
##      10.52608

我还建议在读取CSV中的数据后立即强制转换为矩阵,因为这些表实际上更适合矩阵类型而不是data.frame类型。这是因为你没有异构列;所有列和列类型都是同类的,这是矩阵的特征。我只想将read.csv()来电包裹在as.matrix()

Laender <- as.matrix(read.csv('path/file.csv',row.names=1,check.names=F));
df <- as.matrix(read.csv('path/file1.csv',row.names=1,check.names=F));

然后,您可以省略as.matrix()行中的tapply()来电,这样会变得非常简洁:tapply(df,Laender,mean);

另外,只是添加一件事,如果您确实想手动计算平均值,那么比循环遍历每个单元格更好:您可以将Laender与状态名称进行比较以获得逻辑矩阵,然后使用它来索引df以获取该状态的值,然后取平均值:

mean(df[Laender=='BadenW']);
## [1] 10.35327

事实上,将上述内容与c()unique()sapply()相结合,我们可以在tapply()的帮助下完成整个任务:

sapply(unique(c(as.matrix(Laender))),function(s) mean(df[Laender==s]));
##       Sachsen   MVorpommern        Bremen        RPfalz       SAnhalt
##      10.87170      10.66969      10.57423      10.54924      10.49251
##   Brandenburg     SHolstein        Bayern        BadenW   NRWestfalen
##      11.09401      10.51719      10.30455      10.35327      11.09304
##        Hessen        Berlin Niedersachsen    Thueringen      Saarland
##      10.55788      10.80498      10.90239      10.52608      10.48975
##       Hamburg
##      11.05088