Сочетание изменения формы и агрегации data.frame - PullRequest
1 голос
/ 08 апреля 2020

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

Outcome1  Outcome2  Num_Occurances Name
False       False       2          John Doe
False       True        2          John Doe
True        False       4          John Doe
True        True        2          John Doe
False       True        1          Sally Doe
True        False       1          Sally Doe

Я хотел бы преобразовать и объединить данные в более широкий формат, чтобы в итоге выглядело так:

  • success_outcome2 - сумма истинных значений в Outcome2
  • Total_Occurances - это сумма Num_Occurances для каждого имени.
  • success_outcome1 - это, где Outcome1 и Outcome2 равны True
  • Total_Occurances_Outcome1 - сумма всех истинных ответов в категории Outcome1
Name        successful_Outcome2  Total_Occurances  successful_Outcome1    Total_Occurances_Outcome1 
John Doe           4                  10                   2                        6
Sally Doe          1                   2                   0                        1

Я понимаю, что функцию dcast можно использовать для слияния и преобразования данных в широкий формат, но комбинация разных результатов бросает мне вызов за oop. Любая помощь будет оценена!

Ответы [ 3 ]

2 голосов
/ 08 апреля 2020

Базовое решение R с aggregate + transform, т. Е.

dfout <- aggregate(.~Name,
                   transform(df,
                             successful_outcome2 = Outcome2*Num_Occurances,
                             Total_Occurances = Num_Occurances,
                             successful_Outcome1 = Outcome1*Outcome2*Num_Occurances,
                             Total_Occurances_Outcome1 = Outcome1*Num_Occurances),
                   sum)[-(2:4)]

с урожайностью

> dfout
       Name successful_outcome2 Total_Occurances successful_Outcome1 Total_Occurances_Outcome1
1  John Doe                   4               10                   2                         6
2 Sally Doe                   1                2                   0                         1

ДАННЫЕ

df <- structure(list(Outcome1 = c(FALSE, FALSE, TRUE, TRUE, FALSE, 
TRUE), Outcome2 = c(FALSE, TRUE, FALSE, TRUE, TRUE, FALSE), Num_Occurances = c(2L, 
2L, 4L, 2L, 1L, 1L), Name = c("John Doe", "John Doe", "John Doe", 
"John Doe", "Sally Doe", "Sally Doe")), class = "data.frame", row.names = c(NA, 
-6L))
0 голосов
/ 08 апреля 2020

Один способ - сначала расширить фрейм данных, а затем просто суммировать все:

library(dplyr)
library(tidyr)

df[rep(1:nrow(df), df$Num_Occurances), -3] %>%
  group_by(Name) %>%
  summarise(successful_outcome2=sum(Outcome2),
            Total_Occurances=n(),
            successful_outcome1=sum(Outcome1 & Outcome2),
         Total_Occurances_Outcome1=sum(Outcome1))
# A tibble: 2 x 5
  Name  successful_outcome2 Total_Occurances successful_outcome1 Total_Occurances_Outcome1
  <chr>                <int>            <int>              <int>                     <int>
1 John Doe                 4               10                   2                        6
2 Sally Doe                1                2                   0                        1

Данные :

df <- structure(list(Outcome1 = c(FALSE, FALSE, TRUE, TRUE, FALSE, 
TRUE), Outcome2 = c(FALSE, TRUE, FALSE, TRUE, TRUE, FALSE), Num_Occurances = c(2L, 
2L, 4L, 2L, 1L, 1L), Name = c("John Doe", "John Doe", "John Doe", 
"John Doe", "Sally Doe", "Sally Doe")), class = "data.frame", row.names = c(NA, 
-6L))
0 голосов
/ 08 апреля 2020

Использование dplyr:

library(dplyr)

df %>%
 mutate_at(vars(starts_with('Outcome')), as.logical) %>%
 group_by(Name) %>%
 summarise(successful_Outcome2 = sum(Num_Occurances[Outcome2]),
           Total_Occurances = sum(Num_Occurances), 
           successful_outcome1 = sum(Num_Occurances[Outcome1 & Outcome2]), 
            Total_Occurances_Outcome1 = sum(Num_Occurances[Outcome1]))


#  Name     successful_Outcome2 Total_Occurances successful_outcome1 Total_Occurances_Outcome1
#  <fct>                  <int>            <int>               <int>                     <int>
#1 JohnDoe                    4               10                   2                         6
#2 SallyDoe                   1                2                   0                         1
...