2017-04-06 110 views
4

我有一個單獨的數據幀(姑且稱之爲DF),看起來像這樣:拆分一個數據幀中的所有列,並創建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) 

目標:在每個單元有是由「/」分隔的兩個數字。創建兩個數據幀:1個數據幀,其中包含LEFT號碼,另一個數據幀包含RIGHT號碼。

最終的結果將理想是這樣的:

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 

我用strsplit()但是這是爲了在一個數據幀內將一列分成兩份。我也嘗試了tidyr包中的separate()函數,但需要給定列的名稱。我遍歷所有這些。我想我可以寫一個循環,但是我想知道是否有人有更簡單的方法來做到這一點!

謝謝!

回答

7

試試這個:

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

purrr包的另一種選擇:

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

不是很優雅,但它很短,它的工作原理...

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)))