Суммирование базы данных столбцов в R - PullRequest
0 голосов
/ 07 мая 2018

Я начинаю использовать R, и вполне возможно, что мой вопрос прост, но тем не менее я потратил много времени, пытаясь понять, что я делаю неправильно, но безрезультатно.

Я должен поблагодарить вас, потому что я обнаружил этот сайт на прошлой неделе в поисках других вопросов. Но теперь, как кто-то новый, часто трудно интерпретировать чужой код.

Моя версия RStudio: 1.1.442

Мой вопрос заключается в том, что у меня есть два фрейма данных, один с несколькими годами, а другой с некоторыми элементами, которые были найдены в нескольких тралах, и мне нужно суммировать элементы и сделать другую переменную. Которые появляются суммированием предметов за год и тралом.

Итак, я сделал цикл для того, чтобы иметь одинаковые донные тралы и один и тот же год для суммирования элементов.

Я упростил свою базу данных.

BT<- c(1, 1, 2, 2, 2, 3, 3, 3, 3, 3)
YEAR<- c(2007, 2007, 2008, 2008, 2008, 2009, 2009, 2009, 2009, 2009)
W<- c(95, 6, 60, 50, 4, 21, 56, 44, 23, 4) 
Data1= data.frame(BT,YEAR,W)

Trawl<- c(1, 2, 3)
Year<- c(2007, 2008, 2009)
Data2= data.frame(Trawl,Year)
peso=cbind()

for(i in 1:length(Data1$BT)) {
  ind=which(Data2$Trawl == Data1$BT[i] & Data2$Year == Data1$YEAR[i])

  print(i)
  print(ind)
  print(Data1$W[ind])
  peso[i]=Data1$W[ind]
  sumaGr[i]=colSums(peso[i])
}

И я получаю это:

Ошибка в столбцах (песо [i]): 'x' должен быть массивом как минимум двух измерений

Но я не знаю, как это исправить. Буду признателен за вашу помощь и советы. Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 07 мая 2018

Вы, кажется, реализуете некоторые вычисления split-apply-comb.Вот несколько способов сделать это.

База R

Data3 <- aggregate(Data1$W, by = list(Data1$BT, Data1$YEAR), sum)
colnames(Data3) <- c("Trawl", "YEAR", "sumaGr")
Data3

С dplyr

Data3 <- Data1 %>%
  group_by(BT, YEAR) %>%
  summarise(sumaGr = sum(W)) %>%
  rename(Trawl = BT)
Data3

С data.table

library(data.table)
Data3 <- setDT(Data1)[,.(sumaGr = sum(W)), by = .(BT, YEAR)]
setnames(Data2, "BT", "Trawl")
Data3

Вот вывод из базового решения R:

#   Trawl YEAR sumaGr
# 1     1 2007    101
# 2     2 2008    114
# 3     3 2009    148
0 голосов
/ 07 мая 2018
if(!require(dplyr)) {
  install.packages("dplyr")
  require(dplyr) 
} # for 'inner_join()' install and/or load package dplyr


# Rename for fusion of the two data frames
colnames(Data1) <- c("BT", "Year", "W")
# colnames for 'By=' must look the same!

data1.new <- inner_join(Data1, Data2, by="Year")

# inspect data1.new
data1.new

# split by "Trawl"
df.list <- split(data1.new, data1.new$Trawl)

# summarize each of the data frames in this list
summaries.list <- lapply(df.list, summary)

# But I think what youw ant is colMeans, colSums etc.
colMeans.list <- lapply(df.list, colMeans)
colSums.list  <- lapply(df.list, colSums)

# colMeans(df) is acatually function(df) {apply(df, 2, FUN=mean)}
# in this way you can use any variadic function to make it
# applicable to a whole column (variadic functions are those
# which can take any number of arguments).
# if there is a non-variadic function - let's say max():
# let's say
# max() takes only two arguments (that's not true ...)
# but let's assume it takes only two arguments, then 
# function(your.vector) Reduce(max, your.vector) makes it variadic
# e.g. maximum of a column:
colMax <- function(df) {apply(df, 2, FUN=function(vec) Reduce(max, vec))}
colMax.list   <- lapply(df.list, colMax)

# inspect those objects
colMeans.list
colSums.list
colMax.list

# you can reduce the results using Reduce(rbind, ...)
means.by.trawl.mat <- Reduce(rbind, colMeans.list)
sums.by.trawl.mat  <- Reduce(rbind, colSums.list)
maxs.by.trawl.mat  <- Reduce(rbind, colMax.list)

# give rownames
rownames(means.by.trawl.mat) <- means.by.trawl.mat[, "BT"]
rownames(sums.by.trawl.mat)  <- sums.by.trawl.mat[, "BT"]
rownames(maxs.by.trawl.mat)  <- maxs.by.trawl.mat[, "BT"]

# result
> means.by.trawl.mat
  BT Year    W Trawl
1  1 2007 50.5     1
2  2 2008 38.0     2
3  3 2009 29.6     3
> sums.by.trawl.mat
   BT  Year   W Trawl
2   2  4014 101     2
6   6  6024 114     6
15 15 10045 148    15
> maxs.by.trawl.mat
  BT Year  W Trawl
1  1 2007 95     1
2  2 2008 60     2
3  3 2009 56     3
0 голосов
/ 07 мая 2018
library(dplyr)
df <- inner_join(Data1, Data2, by=c("YEAR"="Year"))

df %>% group_by(Year, Trawl) %>% mutate(sum = sum(W), avg = mean(W))

# A tibble: 10 x 6
# Groups:   Year, Trawl [3]
        BT  Year     W Trawl   sum   avg
      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
  1    1. 2007.   95.    1.  101.  50.5
  2    1. 2007.    6.    1.  101.  50.5
  3    2. 2008.   60.    2.  114.  38.0
  4    2. 2008.   50.    2.  114.  38.0
  5    2. 2008.    4.    2.  114.  38.0
  6    3. 2009.   21.    3.  148.  29.6
  7    3. 2009.   56.    3.  148.  29.6
  8    3. 2009.   44.    3.  148.  29.6
  9    3. 2009.   23.    3.  148.  29.6
 10    3. 2009.    4.    3.  148.  29.6

df %>% group_by(Year, Trawl) %>% summarise(sum = sum(W), avg = mean(W))

# A tibble: 3 x 4
# Groups:   Year [?]
   Year Trawl   sum   avg
  <dbl> <dbl> <dbl> <dbl>
 1 2007.    1.  101.  50.5
 2 2008.    2.  114.  38.0
 3 2009.    3.  148.  29.6
...