2017-04-06 113 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)))