2012-05-29 2 views
1

Я новичок в R, и я написал код для обобщения данных из CSV-файла в соответствии с моими потребностями.суммировать данные из csv, используя R

вот код.

raw <- read.csv("trees.csv") 

выглядит как приходит этот

        SNAME  CNAME  FAMILY PLOT INDIVIDUAL CAP H 
1 Alchornea triplinervia (Spreng.) M. Arg. Tainheiro Euphorbiaceae 5  176 15 9.5 
2    Andira fraxinifolia Benth. Angelim  Fabaceae 3  321 12 6.0 
3    Andira fraxinifolia Benth. Angelim  Fabaceae 3  326 14 7.0 
4    Andira fraxinifolia Benth. Angelim  Fabaceae 3  327 18 5.0 
5    Andira fraxinifolia Benth. Angelim  Fabaceae 3  328 12 6.0 
6    Andira fraxinifolia Benth. Angelim  Fabaceae 3  329 21 7.0 

#add 2 other rows 
for (i in 1:nrow(raw)) { 
    raw$VOLUME[i] <- treeVolume(raw$CAP[i],raw$H[i]) 
    raw$BASALAREA[i] <- treeBasalArea(raw$CAP[i]) 
} 

#here. Мне нужен новый фрейм данных со средними столбцами H и CAP и суммами столбцов VOLUME и BASALAREA. Этот блок данных сгруппирован по столбцу SNAME и подгруппирован столбцом PLOT.

plotSummary = merge(
    aggregate(raw$CAP ~ raw$SNAME * raw$PLOT, raw, mean), 
    aggregate(raw$H ~ raw$SNAME * raw$PLOT, raw, mean)) 

plotSummary = merge(
    plotSummary, 
    aggregate(raw$VOLUME ~ raw$SNAME * raw$PLOT, raw, sum)) 


plotSummary = merge(
    plotSummary, 
    aggregate(raw$BASALAREA ~ raw$SNAME * raw$PLOT, raw, sum)) 

Функции treeVolume и treeBasal area просто возвращают числа.

treeVolume <- function(radius, height) { 
    return (0.000074230*radius**1.707348*height**1.16873) 
} 

treeBasalArea <- function(radius) { 
    return (((radius**2)*pi)/40000) 
} 

Я уверен, что есть лучший способ сделать это, но как?

+3

Do ....... what? –

+0

замените уродливый 4 агрегат на что-то менее повторяющееся – fandreacci

+0

@ user1424495 Хотя хорошо видеть, что вы пробовали, поэтому у нас есть идея, что улучшить, если вы считаете, что ваш код «уродливый», может быть, вы могли бы рассказать нам слова, что есть. Комментарий '#здесь приходит 'не очень помогает. – Gregor

ответ

2

Я не могу прочитать ваши данные примера, но я думаю, что сделал что-то, что в целом представляет его ... так что дайте этому вихрь. Этот ответ основывается на предположении Грега посмотреть на plyr и функции ddply для группировки по сегментам вашего data.frame и numcolwise для расчета вашей интересующей статистики.

#Sample data 
set.seed(1) 
dat <- data.frame(sname = rep(letters[1:3],2), plot = rep(letters[1:3],2), 
        CAP = rnorm(6), 
        H = rlnorm(6), 
        VOLUME = runif(6), 
        BASALAREA = rlnorm(6) 
       ) 


#Calculate mean for all numeric columns, grouping by sname and plot 
library(plyr) 
ddply(dat, c("sname", "plot"), numcolwise(mean)) 
#----- 
    sname plot  CAP  H VOLUME BASALAREA 
1  a a 0.4844135 1.182481 0.3248043 1.614668 
2  b b 0.2565755 3.313614 0.6279025 1.397490 
3  c c -0.8280485 1.627634 0.1768697 2.538273 

EDIT - ответ на обновленный вопрос

Ok - теперь ваш вопрос более или менее воспроизводимым, вот как я бы подойти к нему. Прежде всего, вы можете воспользоваться тем фактом, что R - это vectorized, что означает, что вы можете рассчитать ВСЕ значения из VOLUME и BASALAREA за один проход, не пробираясь через каждую строку. Для этого бита, я рекомендую transform функцию:

dat <- transform(dat, VOLUME = treeVolume(CAP, H), BASALAREA = treeBasalArea(CAP)) 

Во-вторых, понимая, что вы намерены вычислить различные статистические данные для CAP & H, а затем VOLUME & BASALAREA, я рекомендую использовать функцию summarize, как это:

ddply(dat, c("sname", "plot"), summarize, 
    meanCAP = mean(CAP), 
    meanH = mean(H), 
    sumVOLUME = sum(VOLUME), 
    sumBASAL = sum(BASALAREA) 
) 

который даст вам выход, который выглядит как:

sname plot meanCAP  meanH sumVOLUME  sumBASAL 
1  a a 0.5868582 0.5032308 9.650184e-06 7.031954e-05 
2  b b 0.2869029 0.4333862 9.219770e-06 1.407055e-05 
3  c c 0.7356215 0.4028354 2.482775e-05 8.916350e-05 

Страницы помощи для ?ddply, ?transform, ?summarize должны быть проницательными.

+0

Спасибо, человек, это то, что я хотел! – fandreacci

0

Посмотрите на пакет plyr. Я разделил данные с помощью переменной SNAME для вас, затем вы дадите ей код, чтобы сделать набор сводок, которые вы хотите (смешение средних и сумма и т. Д.), Затем он вернет части обратно для вас. Вероятно, вы хотите использовать функцию «ddply» или «daply» в этом пакете.