2017-08-16 1 views
1

Je suis en train de faire un chaud codage de la trame de données de caractères ci-dessous dans l'affaire R.Étendre une chaîne à plusieurs colonnes en R

x1 <- c('') 
x2 <- c('A1,A2') 
x3 <- c('A2,A3,A4') 
test <- as.data.frame(rbind(x1,x2,x3)) 

Je suis en train de mettre les données au format:

x1 <- c(0,0,0,0) 
x2 <- c(1,1,0,0) 
x3 <- c(0,1,1,1) 
result <- as.data.frame(rbind(x1,x2,x3)) 
names(result) = c('A1','A2','A3','A4') 

le séparateur utilisé est une virgule et je peux diviser sur la virgule en utilisant:

test$V1 = as.character(test$V1) 
split_list = strsplit(test$V1, ",") 

Cela me donne une liste de listes qui Cann ot être contraint directement dans un dataframe. Existe-t-il une meilleure façon de le faire. J'essayais "https://www.rdocumentation.org/packages/CatEncoders/versions/0.1.0/topics/OneHotEncoder.fit". Le paquet étalait une seule colonne plutôt que plusieurs colonnes comme nécessaire dans ce cas.

+0

'test%>% Tibble :: rownames_to_column()%> % tidyr :: separate_rows (V1)%>% table() 'vous arrive presque là et est peut-être plus simple que les réponses ici. – Axeman

Répondre

1

Une fonction personnalisée pour diffuser les chaînes uniques valeurs en colonnes:

x1 <- c('') 
x2 <- c('A1,A2') 
x3 <- c('A2,A3,A4') 
test <- data.frame(col1=rbind(x1,x2,x3), stringsAsFactors = F) # test$col1 is a character column 

cast_variables <- function(df, variable){ 
    df[df==""] <- "missing" #handling missingness 
    x <- as.character(unique(df[[variable]])) 
    x <- gsub(" ", "", toString(x)) #so it can split on strings like "A1,A2" and "A1, A2" 
    x <- unlist(strsplit(x, ",")) 
    x <- as.character(x) 
    new_columns <- unique(sort(x))[-grep("missing", unique(sort(x)))] 
    for (i in seq_along(new_columns)){ 
    df$temp <- NA 
    df$temp <- ifelse(grepl(new_columns[i], df[[variable]]), 1, 0) 
    colnames(df)[colnames(df) == "temp"] <- new_columns[i] 
    } 
    return(df) 
} 

test <- cast_variables(test, "col1") 
print(test) 
#  col1 A1 A2 A3 A4 
#x1 missing 0 0 0 0 
#x2 A1,A2 1 1 0 0 
#x3 A2,A3,A4 0 1 1 1 
0

Voici une méthode utilisant un tuyau:

library(dplyr) 
library(tidyr) 
library(reshape2) 
library(data.table) 

test$V1 %>% 
    strsplit(., ",") %>% 
    setNames(row.names(test)) %>% 
    melt(value.name = 'variable') %>% 
    mutate(dummy = 1) %>% 
    spread(key = variable, value = dummy) %>% 
    list(data.frame(L1 = rownames(test)[!rownames(test) %in% .[['L1']]]), .) %>% 
    rbindlist(., use.names = T, fill = T) %>% 
    mutate_all(funs(replace(., is.na(.), 0))) 

# L1 A1 A2 A3 A4 
# 1 x1 0 0 0 0 
# 2 x2 1 1 0 0 
# 3 x3 0 1 1 1