在dplyr mutate调用中添加多个列

时间:2014-07-24 14:21:46

标签: 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

我希望将该列拆分为两个新列,其中包含点两侧的部分。来自包str_split_fixed的{​​{1}}可以很好地完成这项工作。我的所有值肯定是用点分隔的两个部分,所以我可以这样做:

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" 到我的数据框,但我想我会想出如何在cbind管道中做到这一点。首先,我认为dplyr可以在一个中完成:

mutate

我可以让> tst %.% mutate(parts=str_split_fixed(y,"\\.",2)) Error: wrong result size (20), expected 10 or 1 分两次完成:

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 的方式做到这一点(这是我在写这个问题时才发现的......):

dplyr

这不错,但在R中丢失了大量的管道事物的可读性。是否有一种使用> 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 的简单方法我错过了?

2 个答案:

答案 0 :(得分:37)

您可以将separate()中的tidyrdplyr结合使用:

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

设置remove=TRUE将删除第y列

答案 1 :(得分:1)

This answer在这里也适用;以下方法是tidyverse惯用语和more performant than separate()(截至2020年):

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

library(dplyr)
library(purrr)

tst %>% 
  mutate(tmp_chunks = stringr::str_split(y, fixed("."),  n = 2)) %>%
  mutate(y1 = map_chr(tmp_chunks, 1),
         y2 = map_chr(tmp_chunks, 2)) %>%
  select(-tmp_chunks)

...或者,如果不想在拆分后y,可以将最后一行更改为

  select(-tmp_chunks, -y)