拆分一个数据帧中的所有列,并在R中创建两个数据帧

时间:2017-04-06 19:43:52

标签: r dataframe strsplit

我有一个数据框(让我们称之为df),如下所示:

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(),但这是用于在一个数据帧中将1列拆分为两个。我也尝试了tidyr包中的separate()函数,但这需要给定列的名称。我正在遍历所有这些。我想我可以写一个循环,但是我想知道是否有人有更简单的方法来实现这一点!

谢谢!

3 个答案:

答案 0 :(得分: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

答案 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

答案 2 :(得分: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)))