2015-08-17 2 views
2

Я новичок в R, поэтому я не уверен, что аналогичный вопрос уже задан, но поиск не дал мне ответа, который мне нужен.Сравнение значений в одном и том же положении двух одинаковых данных.frames в R

Имея два вида данных. Кадры с таким же количеством столбцов (321) и строк (281), упорядоченными по широте и долготе. DF1 («Лендер») содержит немецкие государства в качестве символов. Это выглядит так:

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.

Надеюсь, есть более простой и быстрый способ сделать это.

+0

Можете ли вы предоставить дополнительную информацию о содержимом этих DF2? Может быть, показать результат 'str (DF2)' для одного из них? – ulfelder

+0

Если ваши 'dfs' имеют одинаковую длину, вы можете запускать множество строк за строкой [сравнения] (http://www.cookbook-r.com/Manipulating_data/Comparing_data_frames/). Кажется, что на ваши вопросы есть два элемента, один из которых касается эффективного способа сравнения кадров данных, а другой - эффективного способа получения сводной статистики. Предположительно, было бы целесообразно использовать 'dplyr' или' aggregate' для более эффективного получения некоторых желаемых мер, но это трудно сказать, не глядя на образец данных и воспроизводимый пример. – Konrad

+0

DF2s выглядят точно так же, как «Laender», но имеют числовые значения вместо символов: 'data.frame': \t 321 obs.из 281 переменных: $ V30: int 0 1 1 7 5 5 0 0 0 0 ... $ V31: int 0 2 2 3 5 2 1 0 0 0 ... $ V32: int 0 1 1 3 2 2 1 0 0 0 ... $ V33: int 0 1 1 3 4 4 1 0 0 0 ... $ V34: int 0 1 0 0 4 4 2 0 0 0 ... $ V35: int 0 0 0 0 24 24 1 0 0 0 ... $ V36: int 0 0 0 0 30 30 1 0 0 0 ... $ V37: int 0 0 0 0 30 8 0 0 0 0 ... $ V38: int 0 0 0 0 8 5 9 0 0 0 ... $ V39: int 0 1 0 0 5 5 10 0 0 0 ... $ V40: int 0 0 0 0 3 10 10 0 0 0. .. ... – brnwa

ответ

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 
+0

tapply() - это именно то, что мне нужно, спасибо! Я бы рекомендовал изменить последнюю часть основного кода: tapply (as.matrix (df [1: 6,1: 6]), as.matrix (Laender [1: 6,1: 6]), среднее значение) На первый взгляд было немного запутанно видеть значения под состояниями без какой-либо корреляции с изображенными таблицами. – brnwa

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