R заменяет вложенные циклы на dplyr, когда поиск столбца происходит из другого data.frame - PullRequest
2 голосов
/ 18 апреля 2020

Суть этого вопроса заключается в использовании dplyr, когда информация group_by поступает из фрейма data.frame, отличного от суммируемых единиц. Пример: я назначил места группам в других местах. Каждое уникальное назначение набора местоположений группам - это один план. Есть тысячи планов. Я ищу сводную статистику по каждому плану.

Я делаю это медленно, для l oop и хотел бы максимально ускорить процесс. Я ожидаю, что смогу сделать это с group_by и суммировать, но синтаксис ускользает от меня, и во всех примерах, которые я нахожу, есть поиски из того же тиббла или data.frame. Воспроизводимый пример:

# locations (x,y), populations at those locations (popA, popB)   
df <- data.frame(x = rep(1:3, times = 3),
                 y = c(1,1,1,2,2,2,3,3,3),
                 popA = c(1,2,3,4,5,6,7,8,9),
                 popB = c(10,11,12,13,14,15,16,17,18))

# plans (Runs 1 through 3) each plan is a column in the data.frame and the
# value indicates the group to which each location was assigned in that plan  
result < -data.frame(Run1 = c(1,1,1,2,2,2,3,3,3),
                     Run2 = c(1,2,3,1,2,3,1,2,3),
                     Run3 = c(1,1,3,2,2,3,3,3,3))

#The data.frame where I will store my summary statistics.    
#Plan | District | Pop A | Pop B | Total
pop.by.dist <- data.frame(Plan = rep(NA,(max(result$Run1))*length(colnames(result))),
                          District = NA, PopA = NA, PopB = NA, Total = NA)

counter = 1
for(i in 1:length(colnames(result))){ #for every plan
  for(j in 1:max(result)){ #for every district
    tmp <- colSums(df[result[,i]==j,c("popA","popB")])
    pop.by.dist[counter,] <- c(colnames(result)[i],j,tmp,sum(tmp))
    counter <- counter+1
  }
}
pop.by.dist #output has one row per plan * district combination

    #> pop.by.dist
    #  Plan District PopA PopB Total
    #1 Run1        1    6   33    39
    #2 Run1        2   15   42    57
    #3 Run1        3   24   51    75
    #4 Run2        1   12   39    51
    #5 Run2        2   15   42    57
    #6 Run2        3   18   45    63
    #7 Run3        1    3   21    24
    #8 Run3        2    9   27    36
    #9 Run3        3   33   78   111

Я знаю, что здесь уже есть огромное количество связанных вопросов, но конкретный c должен иметь поиск из другого data.frame, который мне было трудно найти. Я не новый пользователь и потратил некоторое время на поиски ответа, который я смог бы получить, поэтому прежде чем вы пометите меня как повтор, просто включите код для решения моей проблемы. Вы могли бы просто помочь следующему человеку.

1 Ответ

0 голосов
/ 18 апреля 2020

Если нет проблем с простым связыванием двух фреймов данных, сделайте это сначала:

new_df <- cbind(df, result)

Затем вы переводите данные в длинный формат, затем группируете, затем суммируете:

new_df %>% pivot_longer(c(Run1, Run2, Run3), 
                        names_to = "Plan", 
                        values_to = "District") %>% 
  group_by(Plan, District) %>% 
  summarise_at(vars(popA, popB), sum) %>%
  mutate(Total = popA + popB)
# A tibble: 9 x 5
# Groups:   Plan [3]
  Plan  District  popA  popB Total
  <chr>    <dbl> <dbl> <dbl> <dbl>
1 Run1         1     6    33    39
2 Run1         2    15    42    57
3 Run1         3    24    51    75
4 Run2         1    12    39    51
5 Run2         2    15    42    57
6 Run2         3    18    45    63
7 Run3         1     3    21    24
8 Run3         2     9    27    36
9 Run3         3    33    78   111
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...