在dplyr mutate调用中添加多个列

Spa*_*man 20 r dplyr

我有一个带点分隔字符列的数据框:

> set.seed(310366)
> tst = data.frame(x=1:10,y=paste(sample(c("FOO","BAR","BAZ"),10,TRUE),".",sample(c("foo","bar","baz"),10,TRUE),sep=""))
> tst
    x       y
1   1 BAR.baz
2   2 FOO.foo
3   3 BAZ.baz
4   4 BAZ.foo
5   5 BAZ.bar
6   6 FOO.baz
7   7 BAR.bar
8   8 BAZ.baz
Run Code Online (Sandbox Code Playgroud)

我想将该列拆分为两个新列,其中包含点两侧的部分.str_split_fixed从包中stringr可以很好地完成这项工作.我的所有值肯定是用点分隔的两个部分,所以我可以这样做:

> require(stringr)
> str_split_fixed(tst$y,"\\.",2)
      [,1]  [,2] 
 [1,] "BAR" "baz"
 [2,] "FOO" "foo"
 [3,] "BAZ" "baz"
 [4,] "BAZ" "foo"
 [5,] "BAZ" "bar"
 [6,] "FOO" "baz"
 [7,] "BAR" "bar"
Run Code Online (Sandbox Code Playgroud)

现在我可以把cbind它放到我的数据框架上,但我想我会弄清楚如何在dplyr管道中做到这一点.首先,我认为mutate可以做到一个:

> tst %.% mutate(parts=str_split_fixed(y,"\\.",2))
Error: wrong result size (20), expected 10 or 1
Run Code Online (Sandbox Code Playgroud)

我可以mutate用两个来做:

> tst %.% mutate(part1=str_split_fixed(y,"\\.",2)[,1], part2=str_split_fixed(y,"\\.",2)[,2])
    x       y part1 part2
1   1 BAR.baz   BAR   baz
2   2 FOO.foo   FOO   foo
3   3 BAZ.baz   BAZ   baz
4   4 BAZ.foo   BAZ   foo
5   5 BAZ.bar   BAZ   bar
6   6 FOO.baz   FOO   baz
Run Code Online (Sandbox Code Playgroud)

但那是两次运行字符串.

"最好的"我在dplyr某种程度上可以做到这一点(我在写这个问题时才发现......):

> tst %.% do(cbind(.,data.frame(parts=str_split_fixed(.$y,"\\.",2))))
    x       y parts.1 parts.2
1   1 BAR.baz     BAR     baz
2   2 FOO.foo     FOO     foo
3   3 BAZ.baz     BAZ     baz
4   4 BAZ.foo     BAZ     foo
5   5 BAZ.bar     BAZ     bar
Run Code Online (Sandbox Code Playgroud)

这还不错,但在R中失去了管道事物的很多可读性.是否有一个简单的方法使用mutate我错过了?

bee*_*oot 37

您可以使用separate()tidyr与组合dplyr:

tst %>% separate(y, c("y1", "y2"), sep = "\\.", remove=FALSE)

    x       y  y1  y2
1   1 BAR.baz BAR baz
2   2 FOO.foo FOO foo
3   3 BAZ.baz BAZ baz
4   4 BAZ.foo BAZ foo
5   5 BAZ.bar BAZ bar
6   6 FOO.baz FOO baz
7   7 BAR.bar BAR bar
8   8 BAZ.baz BAZ baz
9   9 FOO.bar FOO bar
10 10 BAR.foo BAR foo
Run Code Online (Sandbox Code Playgroud)

设置remove=TRUE将删除列y

  • 使用`extra = "merge"` 参数可以控制 (2认同)