2017-09-27 1 views
5

Je travaille avec R et j'ai ces données:Réorganiser une table par groupe

data <- structure(list(Col1 = 1:9, Col2 = structure(c(2L, 2L, 2L, 1L, 
3L, 3L, 3L, 3L, 3L), .Label = c("Administrative ", "National", 
"Regional"), class = "factor"), Col3 = structure(c(NA, 3L, 4L, 
NA, 2L, 3L, 1L, 4L, 3L), .Label = c("bike", "boat", "car", "truck" 
), class = "factor"), Col4 = c(56L, 65L, 58L, 62L, 24L, 25L, 
120L, 89L, 468L), X = c(NA, NA, NA, NA, NA, NA, NA, NA, NA), 
    X.1 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("Col1", 
"Col2", "Col3", "Col4", "X", "X.1"), class = "data.frame", row.names = c(NA, 
-9L)) 

Je voudrais réarranger pour voir ce qui est disponible ou ne. La sortie ressemblerait à ceci:

result <- structure(list(Col1 = c(1L, 4L, 5L), Col2 = structure(c(2L, 1L, 
3L), .Label = c("Administrative ", "National", "Regional"), class = "factor"), 
    car = c(1L, 0L, 1L), truck = c(1L, 0L, 1L), boat = c(0L, 
    0L, 1L), bike = c(0L, 0L, 1L)), .Names = c("Col1", "Col2", 
"car", "truck", "boat", "bike"), class = "data.frame", row.names = c(NA, 
-3L)) 

J'ai essayé avec l'agrégat mais je suis encore loin du résultat. L'aide serait

t <- aggregate(data$Col2, by=list(data$Col3), c) 

L'aide est la bienvenue!

+0

S'il vous plaît ajouter également dans la langue avec laquelle vous travaillez, il est plus facile de trouver de l'aide. –

+0

Édité! C'était dans le titre du sujet :) – Floni

Répondre

4

Nous pouvons utiliser dcast de data.table avec length comme fun.aggregate

library(data.table) 
dcast(setDT(data), Col2~ Col3, length)[, 1:5, with = FALSE] 
+1

Semble fonctionner parfaitement, merci! – Floni

2

Voici une solution dplyr si vous êtes intéressé, bien que la solution de akrun semble plus concise:

library(tidyverse) 

result <- data %>% 
    group_by(Col2, Col3) %>% 
    summarise(tot = sum(Col4)) %>% 
    mutate(bool = if_else(tot > 0, 1, 0)) %>% 
    select(Col2, Col3, bool) %>% 
    spread(key = Col3, value = bool, fill = 0) %>% 
    select(-`<NA>`) 
3

Voici une idée en utilisant base R,

#convert to character 
data[2:3] <- lapply(data[2:3], as.character) 

#get unique elements to tabulate 
i1 <- unique(data$Col3) 
i1 <- i1[!is.na(i1)] 


setNames(data.frame(do.call(rbind, lapply(split(data$Col3, data$Col2), function(i) 
              as.integer(match(i1, i, nomatch = 0) > 0)))), i1) 

qui donne,

   car truck boat bike 
Administrative 0  0 0 0 
National   1  1 0 0 
Regional   1  1 1 1 
1

Voici une autre méthode de base de R à l'aide table et une contrainte.

(table(data$Col2, data$Col3) > 0) + 0L 

        bike boat car truck 
    Administrative  0 0 0  0 
    National   0 0 1  1 
    Regional   1 1 1  1 

table compte les instances, de retour 0 pour les agences nationales. Nous forçons alors à logique avec > 0 pour laisser tomber les valeurs supérieures à 1 et revenir à l'entier avec + 0L.