J'ai une trame de données R des résultats de l'enquête. Chaque colonne est une réponse à une question de l'enquête. Il peut prendre les valeurs 1 à 10 et NA. J'aimerais en faire un tableau de fréquences.
Voici un exemple des données dont je dispose. Je prétends que les valeurs vont de 1 à 3, au lieu de 1 à 10.
data.frame( "Question" = c("Question1", "Question2"), "Frequency of 1" = c(2, 1), "Frequency of 2" = c(0 , 1), "Frequency of 3" = c(0, 1) )
Ce que je veux:
data.frame( "Person" = c(1,2,3), "Question1" = c(NA, "1", "1"), "Question2" = c("1", "2", "3") )
J'ai essayé d'utiliser likert () du package likert, mais j'obtiens des résultats fractionnaires qui ne peuvent pas être corrects. Existe-t-il une solution simple à ce problème?
4 Réponses :
Ce n'est pas le plus élégant mais cela pourrait vous aider: df2 est votre ensemble de données. Données:
Frequency of_1 Frequency of_2 Frequency of_3 Question1 2 0 0 Question2 1 1 1
Cible: EDIT :: Vous pouvez "automatiser" comme suit
df2[is.na(df2)]<-0 #To allow numeric manipulation values<-c("1","2","3") Final_df<-sapply(values,function(val) apply(df2[,-1],2,function(x) sum(x==val))) Final_df<-as.data.frame(Final_df) names(Final_df)<-paste0("Frequency of_",1:ncol(Final_df))
Cela donne:
df2<-data.frame( "Person" = c(1,2,3), "Question1" = c(NA, "1", "1"), "Question2" = c("1", "2", "3"),stringsAsFactors = F )
p >
Une solution data.table
:
dcast(melt(setDT(df), id.vars="Person", value.name="Question")[!Question %in% NA][, Question := paste0("Frequency of ", Question)], variable ~ Question)
Ou une réponse en une ligne:
require(data.table) setDT(df) # Melt data: df <- melt(df, id.vars = "Person", value.name = "Question") # Cast data to required structure: df <- data.frame(dcast(df, variable ~ Question)) # Rename variables and remove NA count (as per Ops question): names(df)[1] <- "Question" names(df)[-1] <- gsub("X", "Frequency of ", names(df)[-1]) df$NA. <- NULL df # Question Frequency of 1 Frequency of 2 Frequency of 3 #1 Question1 2 0 0 #2 Question2 1 1 1
p>
Voici une solution utilisant les packages dplyr et purrr
library(dplyr) library(purrr) data.frame( "Person" = c(1,2,3), "Question1" = c(NA, "1", "1"), "Question2" = c("1", "2", "3") ) df %>% select(-Person) %>% mutate_all(~ factor(.x, levels = as.character(1:10) ) %>% addNA() ) %>% map(table) %>% transpose() %>% map(as.integer) %>% set_names( ~ paste0("Frequency of ",ifelse(is.na(.), "NA", .))) %>% as_tibble() %>% mutate(Question = setdiff(names(df),"Person")) %>% select(Question,everything(), "Frequency of NA" = `Frequency of ` )
Une autre possibilité de tidyverse
pourrait être:
df %>% gather(Question, val, -Person) %>% group_by(Question, val) %>% summarise(res = length(val)) %>% ungroup() %>% mutate(val = paste0("Frequency.of.", val)) %>% spread(val, res, fill = NA) Question Frequency.of.1 Frequency.of.2 Frequency.of.3 Frequency.of.NA <chr> <int> <int> <int> <int> 1 Question1 2 NA NA 1 2 Question2 1 1 1 NA
Ici, il transforme d'abord les données du format large au format long. Deuxièmement, il calcule les fréquences en fonction des questions. Enfin, il crée la «fréquence. variables et renvoie les données à la forme souhaitée.
Ou si vous voulez calculer également les valeurs NA par question:
df %>% gather(Question, val, -Person, na.rm = TRUE) %>% group_by(Question, val) %>% summarise(res = length(val)) %>% ungroup() %>% mutate(val = paste0("Frequency.of.", val)) %>% spread(val, res, fill = NA) Question Frequency.of.1 Frequency.of.2 Frequency.of.3 <chr> <int> <int> <int> 1 Question1 2 NA NA 2 Question2 1 1 1
Pourquoi la question 2 a-t-elle la fréquence de 1 à 0 et celle de 3 à 3 à la question 2?
J'ai fait une erreur. J'ai édité la question.