使用dplyr按组连接字符串

时间:2016-07-21 21:54:23

标签: r dplyr

我的数据框看起来像这样

> data <- data.frame(foo=c(1, 1, 2, 3, 3, 3), bar=c('a', 'b', 'a', 'b', 'c', 'd'))
> data
  foo bar
1   1   a
2   1   b
3   2   a
4   3   b
5   3   c
6   3   d

我想创建一个新列bars_by_foo,它是bar by foo的值的串联。所以新数据应如下所示:

  foo bar bars_by_foo
1   1   a          ab
2   1   b          ab
3   2   a           a
4   3   b         bcd
5   3   c         bcd
6   3   d         bcd

我希望以下内容能够奏效:

p <- function(v) {
  Reduce(f=paste, x = v)
}
data %>% 
  group_by(foo) %>% 
  mutate(bars_by_foo=p(bar))

但是那段代码给了我一个错误

Error: incompatible types, expecting a character vector

我做错了什么?

4 个答案:

答案 0 :(得分:59)

你可以简单地做

data %>% 
     group_by(foo) %>% 
     mutate(bars_by_foo = paste0(bar, collapse = "")) 

没有任何辅助功能

答案 1 :(得分:4)

mutate功能看起来有点问题 - 我发现当你&#39时,summarise使用它是更好的方法;重新分组dplyr中的数据(虽然这并不是一个严格的规则)。

paste函数还会在结果中引入空格,因此要么设置sep = 0,要么只使用paste0

这是我的代码:

p <- function(v) {
  Reduce(f=paste0, x = v)
}

data %>% 
    group_by(foo) %>% 
    summarise(bars_by_foo = p(as.character(bar))) %>%
    merge(., data, by = 'foo') %>%
    select(foo, bar, bars_by_foo)

导致..

  foo bar bars_by_foo
1   1   a          ab
2   1   b          ab
3   2   a           a
4   3   b         bcd
5   3   c         bcd
6   3   d         bcd

答案 2 :(得分:3)

你可以试试这个:

agg <- aggregate(bar~foo, data = data, paste0, collapse="")
df <- merge(data, agg, by = "foo", all = T)
colnames(df) <- c(colnames(data), "bars_by_foo") # optional


  # foo bar bars_by_foo
# 1   1     a    ab
# 2   1     b    ab
# 3   2     a     a
# 4   3     b   bcd
# 5   3     c   bcd
# 6   3     d   bcd

答案 3 :(得分:0)

如果确保条形图是所有字符而不是因子级别,则此功能有效。

data <- data.frame(foo=c(1, 1, 2, 3, 3, 3), bar=c('a', 'b', 'a', 'b', 'c', 'd'),
stringsAsFactors = FALSE)

library("dplyr")

p <- function(v) {
  Reduce(f=paste, x = v)
 }

data %>% 
  group_by(foo) %>% 
  mutate(bars_by_foo=p(bar))


Source: local data frame [6 x 3]
Groups: foo [3]

   foo   bar bars_by_foo
  <dbl> <chr>       <chr>
    1     1     a     a b
    2     1     b     a b
    3     2     a       a
    4     3     b   b c d
    5     3     c   b c d
    6     3     d   b c d