Mam zestaw danych, który wygląda jak:

data1 <- data.frame(id = c(1,1,1, 1, 2, 2, 3, 3), outcome = c(1, 0, 1, 1, 0, 0, 1, 1), month = c("Jan", "Jan", "Feb", "Mar", "Feb", "Mar", "Apr", "Apr"), 
                     gender = c(0, 0, 0, 0, 1, 1, 0, 0), type = c("A", "A", "A", "A", "A", "A", "B", "B"))

> data1
  id outcome month gender type
1  1       1   Jan      0    A
2  1       0   Jan      0    A
3  1       1   Feb      0    A
4  1       1   Mar      0    A
5  2       0   Feb      1    A
6  2       0   Mar      1    A
7  3       1   Apr      0    B
8  3       1   Apr      0    B

Każda osoba jest oznaczona przez id. W tym zestawie danych mam 3 unikalne osoby. Jestem zainteresowany tabulatingiem outcome dla każdej osoby przez month. Moje pożądane wyjście to:

  id outcome1 outcome0 month gender type
1  1        1        1   Jan      0    A
2  1        1        0   Feb      0    A
3  1        1        0   Mar      0    A
4  2        0        1   Feb      1    A
5  2        0        1   Mar      1    A
6  3        2        0   Apr      0    B

Dla każdego id w moim zestawie danych, chcę zwinąć outcome dla każdego month. Jak mogę tabulować moje dane w R?

1
Adrian 25 luty 2021, 08:52

3 odpowiedzi

Najlepsza odpowiedź
library(tidyverse)   # or use:   library(dplyr); library(tidyr)
data1 %>%
  # Count how many observations have each combination of
  # id, outcome, month, etc.
  count(id, outcome, month, gender, type) %>%

  # define new columns named "outcome_#" and populate
  # them with the counts ("n") calc'd in prior step.
  pivot_wider(names_from = outcome, values_from = n, 
              names_prefix = "outcome", values_fill = list(n= 0))

# A tibble: 6 x 6
     id month gender type   outcome0  outcome1
  <dbl> <chr>  <dbl> <chr>     <int>     <int>
1     1 Jan        0 A             1         1
2     1 Feb        0 A             0         1
3     1 Mar        0 A             0         1
4     2 Feb        1 A             1         0
5     2 Mar        1 A             1         0
6     3 Apr        0 B             0         2
1
Jon Spring 25 luty 2021, 08:46

Najpierw Uzyskaj liczbę unikalnych wartości wynikowych według grupy przy użyciu length w ave, a następnie reshape odpowiednio. Nieistniejące kombinacje wydajność NA, które chcesz zastąpić 0.

res <- reshape(transform(data1, z.outcome=ave(id, outcome, month, type, FUN=length)),
          idvar=c(1, 3, 4, 5), v.names="z.outcome", timevar=2, direction="wide")[-2]
res[is.na(res)] <- 0
res
#   id month gender type z.outcome.1 z.outcome.0
# 1  1   Jan      0    A           1           1
# 3  1   Feb      0    A           1           0
# 4  1   Mar      0    A           1           0
# 5  2   Feb      1    A           0           1
# 6  2   Mar      1    A           0           1
# 7  3   Apr      0    B           2           0
0
jay.sf 25 luty 2021, 07:00

Z group_by:

data1 %>% 
  group_by(id, month) %>% 
  summarise(
    outcome1 = sum(outcome == 1), 
    outcome0 = sum(outcome == 0), 
    gender = gender[1],
    type = type[1]
  )

#      id month outcome1 outcome0 gender type 
# 1     1 Feb          1        0      0 A    
# 2     1 Jan          1        1      0 A    
# 3     1 Mar          1        0      0 A    
# 4     2 Feb          0        1      1 A    
# 5     2 Mar          0        1      1 A    
# 6     3 Apr          2        0      0 B  
0
sindri_baldur 25 luty 2021, 09:01