2017-04-06 1 views
4

J'ai une trame de données unique (appelons-le df) qui ressemble à ceci:de Split toutes les colonnes dans une trame de données et créer deux trames de données dans R

col1 <- c("1/10", "2/30", "1/40", "3/23", "0/17", "7/14") 
col2 <- c("2/44", "0/13", "4/55", "6/43", "0/19", "2/34") 
col3 <- c("0/36", "0/87", "3/11", "2/12", "4/33", "0/12") 
col4 <- c("1/76", "2/65", "2/21", "5/0", "2/26", "1/52") 

df <- data.frame(col1,col2,col3,col4) 

BUT: Dans chaque cellule il y a sont deux nombres séparés par un "/". Créez deux trames de données: 1 trame de données avec le numéro LEFT et une autre trame de données avec le numéro RIGHT.

Le résultat final ressemblerait idéalement comme ceci:

df.left.numbers:

col1 col2 col3 col4 
    1 2 0 1 
    2 0 0 2 
    1 4 3 2 
    3 6 2 5 
    0 0 4 2 
    7 2 0 1 

df.right.numbers:

col1 col2 col3 col4 
    10 44 36 76 
    30 13 87 65 
    40 55 11 21 
    23 43 12 0 
    17 19 33 26 
    14 34 12 53 

Je l'ai utilisé StrSplit() mais cela est pour 1 colonne divisant en deux dans un cadre de données. J'ai également essayé la fonction séparée() dans le paquetage tidyr mais cela nécessite le nom d'une colonne donnée. Je répète à travers eux tous. Je suppose que je pourrais écrire une boucle, mais je me demandais si quelqu'un avait un moyen plus facile de rendre cela possible!

Merci!

Répondre

7

Essayez ceci:

require(data.table) 
lapply(split(unlist(
     lapply(df,tstrsplit,"/"),recursive=FALSE),c("Left","Right")), 
      as.data.frame) 

#$Right 
# col12 col22 col32 col42 
#1 10 44 36 76 
#2 30 13 87 65 
#3 40 55 11 21 
#4 23 43 12  0 
#5 17 19 33 26 
#6 14 34 12 52 

#$Left 
# col11 col21 col31 col41 
#1  1  2  0  1 
#2  2  0  0  2 
#3  1  4  3  2 
#4  3  6  2  5 
#5  0  0  4  2 
#6  7  2  0  1 
3

Une autre option avec purrr package:

library(data.table) 
library(purrr) 
df %>% 
     map(tstrsplit, split="/") %>% 
     transpose() %>% map(as.data.frame) %>% 
     set_names(c("left", "right")) 
#$left 
# col1 col2 col3 col4 
#1 1 2 0 1 
#2 2 0 0 2 
#3 1 4 3 2 
#4 3 6 2 5 
#5 0 0 4 2 
#6 7 2 0 1 

#$right 
# col1 col2 col3 col4 
#1 10 44 36 76 
#2 30 13 87 65 
#3 40 55 11 21 
#4 23 43 12 0 
#5 17 19 33 26 
#6 14 34 12 52 
3

Pas très élégant, mais il est court et il fonctionne ...

col1 <- c("1/10", "2/30", "1/40", "3/23", "0/17", "7/14") 
col2 <- c("2/44", "0/13", "4/55", "6/43", "0/19", "2/34") 
col3 <- c("0/36", "0/87", "3/11", "2/12", "4/33", "0/12") 
col4 <- c("1/76", "2/65", "2/21", "5/0", "2/26", "1/52") 

df <- data.frame(col1,col2,col3,col4,stringsAsFactors = FALSE) 

dfLeft <- as.data.frame(lapply(df,function(x) gsub("\\/.+","",x))) 
dfRight <- as.data.frame(lapply(df,function(x) gsub(".+\\/","",x)))