Je sais que la réponse à cette question sera simple, mais j'ai effectué de nombreuses recherches dans les forums et je n'ai pas pu trouver de solution.
J'ai une colonne appelée Data_source
qui est un facteur par lequel je souhaite regrouper mes variables.
J'ai une série de variables symptom *
dont je veux les décomptes selon Data_source
.
Pour une raison quelconque, je n'arrive pas à comprendre comment faire cela. Les fonctions normales de group_by
ne semblent pas fonctionner correctement.
Voici le dataframe en question
> df %>% na.omit() %>% group_by(Data_source) %>% count("symptoms_decLOC") # A tibble: 2 x 3 # Groups: Data_source [2] Data_source `"symptoms_decLOC"` n <chr> <chr> <int> 1 1 symptoms_decLOC 5 2 2 symptoms_decLOC 2
Notez que Sex et les variables des symptômes sont tous des facteurs qui incluent les NA. J'ai essayé ce qui suit
df %>% na.omit() %>% group_by(Data_source) %>% count("symptoms_decLOC")
Ce qui ne fonctionne pas et n'est pas optimal car je devrais le répéter pour chaque colonne. L'idéal serait d'utiliser quelque chose de similaire à lapply (df, count)
mais cela ne me donne pas de description pour chaque groupe.
EDIT
En réponse à la question ci-dessous, j'ai ajouté le résultat attendu. J'ai édité ceci dans Excel, en codant par couleur le group_by
pour plus de clarté.
Remarquez comment je je reçois une ventilation pour chaque réponse possible. Lorsque je l'exécute en utilisant dplyr
, voici la sortie.
df <- wrapr::build_frame( "Data_source" , "Sex" , "symptoms_decLOC", "symptoms_nausea_vomitting" | "1" , "Female", NA_character_ , NA_character_ | "1" , "Female", NA_character_ , NA_character_ | "1" , "Female", "No" , NA_character_ | "1" , "Female", "Yes" , "No" | "1" , "Female", "Yes" , "No" | "1" , "Female", "Yes" , "No" | "1" , "Male" , "Yes" , "No" | "1" , "Female", "Yes" , "No" | "2" , "Female", NA_character_ , NA_character_ | "2" , "Male" , NA_character_ , NA_character_ | "2" , "Male" , NA_character_ , NA_character_ | "2" , "Female", "Yes" , "No" | "2" , "Female", "Yes" , "No" | "2" , "Male" , NA_character_ , NA_character_ | "2" , "Male" , NA_character_ , NA_character_ | "2" , "Male" , NA_character_ , NA_character_ | "2" , "Female", NA_character_ , NA_character_ | "2" , "Female", NA_character_ , NA_character_ | "2" , "Male" , NA_character_ , NA_character_ | "2" , "Female", NA_character_ , NA_character_ )
4 Réponses :
Je ne comprends pas tout à fait ce que vous demandez, mais je suppose que vous voulez compter le nombre de valeurs non-NA dans chacune de vos colonnes symptom_ *
.
Ceci est une solution data.table
:
# load library library(data.table) # Suppose the table is called "dt". Convert it to a data.table: setDT(dt) # convert the wide table to a long one, filter the values that # aren't NA and count both, by Data_source and by variable # (variable is the created column with the symptom_* names) melt(dt, id.vars = 1:2)[!is.na(value), .N, by = .(Data_source, variable)]
Ce que fait chaque partie du code:
melt ( dt, id.vars = 1: 2)
convertit dt
de large en long et conserve les colonnes 1 et 2 (Data_source et sex
) comme fixes.
! is.na (valeur)
filtre les valeurs (qui étaient auparavant sous chaque en-tête symptom_ *
) qui ne sont pas NA code >.
.N
compte les lignes.
by =. (Data_source, variable)
est le regroupement que nous utilisons compter. variable
est le nom de la colonne où le symptom_ *
a atterri lors de la refonte.
Lorsque j'exécute cela, j'obtiens la variable Data_source suivante N 1: 1 symptômes_decLOC 6 2: 2 symptômes_decLOC 2 3: 1 symptômes_nausea_vomitting 5 4: 2 symptômes_nausea_vomitting 2 Cela ne me donne pas de statistiques pour chaque réponse individuelle.
Cela prend la plupart du temps: je n'ai pas encore trouvé comment inclure des groupes à zéro comptage ... soi-disant en ajoutant . drop = FALSE s'occupe de ça , mais cela ne fonctionne pas pour moi (en utilisant dplyr
v. 0.8.0.9001 ).
Data_source var val n <chr> <chr> <chr> <int> 1 1 Sex Female 7 2 1 Sex Male 1 3 1 symptoms_decLOC No 1 4 1 symptoms_decLOC Yes 5 5 1 symptoms_nausea_vomitting No 5 6 2 Sex Female 6 7 2 Sex Male 6 8 2 symptoms_decLOC Yes 2 9 2 symptoms_nausea_vomitting No 2
Résultats:
library(dplyr) library(tidyr) (df %>% tidyr::gather(var,val,-Data_source) %>% count(Data_source,var,val, .drop=FALSE) %>% na.omit() )
En utilisant cette syntaxe, je n'obtiens pas le même résultat que vous. J'obtiens Erreur de décompte (., Data_source, var, val, .drop = FALSE): arguments non utilisés (val, .drop = FALSE)
quels sont les résultats de find ("count")
(et packageVersion ("dplyr") `)?
Voici un lien vers la sortie > find ("count") [1] "package: plyr" "package: dplyr"> packageVersion ("dplyr") [1] '0.8.0.1'
D'accord, puisque les deux packages sont en cours de chargement si je change votre code en dplyr :: count
, j'obtiens le résultat attendu! Merci
Vous avez probablement reçu un avertissement indiquant que certaines fonctions étaient masquées lorsque vous avez chargé plyr
après dplyr
...
Utilisation de la réponse de @Ben Bolker pour obtenir le décompte de chaque groupe, utilisation de spread
et collecte
pour inclure des groupes de comptage nul.
dplyr
library(data.table) dt <- data.table(df) # Melt data by Data source dt_melt <- melt(dt, id.vars = "Data_source", value.factor = FALSE, variable.factor = FALSE) # Add counter, if NA then 0 else 1 dt_melt[, counter := 0] dt_melt[!is.na(value), counter := 1] # Sum number of occurrences dt_count <- dt_melt[,list(counter = sum(counter)), by = c("Data_source", "variable", "value")] # Split into two dt dt2a <- dt_count[variable == "Sex", ] dt2b <- dt_count[variable != "Sex" ,] # only on symptoms variables # Convert into factor variable dt2b$value <- factor(dt2b$value, levels = c("Yes", "No")) dt2b_dcast <- dcast(data = dt2b, formula = Data_source + variable ~ value, value.var = "counter", fill = 0, drop = FALSE) dt2b_melt <- melt(dt2b_dcast, id.vars = c("Data_source", "variable"), variable.name = "value", value.name = "counter") # combine combined_d <- rbind(dt2a, dt2b_melt) combined_d[order(Data_source, variable), ]
library(dplyr)
library(tidyr)
# Count number of occurences by Data_source
df2 <-
df %>%
gather(variable, value, -Data_source) %>%
count(Data_source, variable, value, name = "counter") %>%
na.omit()
# For variable = "Sex", leave as is
# For everything else, in this case symptom* convert into factor to include zero count group
# Then spread with dataframe will NAs filled with 0, re-convert back to long to bind rows
bind_rows(df2 %>%
filter(variable == "Sex"),
df2 %>%
filter(variable != "Sex") %>%
mutate(value = factor(value, levels = c("Yes", "No"))) %>%
spread(key = value, value = counter, fill = 0) %>%
gather(value, counter, -Data_source, -variable)) %>%
arrange(Data_source, variable)
Ya je suis toujours incapable de faire fonctionner la méthode dplyr. Data.table fonctionne mais il ajoute une énorme quantité de code.
Décidément, le plus dur est de conserver des combinaisons qui n'existent pas dans les données ... Voici une solution en deux étapes:
1. Préparez une base de données sans décompte
Vous pouvez faire ce que vous voulez, mais j'ai choisi de calculer deux blocs car les modalités sont différentes pour la variable Sex
. Pas besoin de lier ces morceaux ici.
# A tibble: 12 x 4 # Groups: Data_source, name [6] Data_source name value count <chr> <chr> <chr> <int> 1 1 Sex Female 7 2 1 Sex Male 1 3 1 symptoms_decLOC Yes 5 4 1 symptoms_decLOC No 1 5 1 symptoms_nausea_vomitting Yes 0 6 1 symptoms_nausea_vomitting No 5 7 2 Sex Female 6 8 2 Sex Male 6 9 2 symptoms_decLOC Yes 2 10 2 symptoms_decLOC No 0 11 2 symptoms_nausea_vomitting Yes 0 12 2 symptoms_nausea_vomitting No 2
2. Terminer le travail demandé
library(dplyr) library(tidyr) df %>% pivot_longer(cols = c("Sex", "symptoms_decLOC", "symptoms_nausea_vomitting"))%>% group_by(Data_source, name, value) %>% summarise(count = n()) %>% right_join(bind_rows(chunk1, chunk2), by = c("Data_source", "name", "value")) %>% arrange(Data_source, name) %>% mutate(count = zoo::na.fill(count, 0))
Et voilÃ
chunk1 <- expand.grid( Data_source = c("1", "2"), name = c("symptoms_decLOC", "symptoms_nausea_vomitting"), value = c("Yes", "No"), stringsAsFactors = FALSE ) chunk2 <- expand.grid( Data_source = c("1", "2"), name = "Sex", value = c("Female", "Male"), stringsAsFactors = FALSE )
Ce n'est pas si court, mais il utilise des fonctions simples. Le processus est similaire à celui que l'on peut faire dans Excel, c'est-à-dire préparer la structure puis compléter les comptages.
J'espère que cela pourrait aider ;-)
quelle est votre sortie souhaitée?
Merci pour votre commentaire. J'aurais dû mettre cela dans la question initiale. J'ai fait un EDIT pour clarifier davantage ce que je recherche