Question Concaténer des chaînes par groupe avec dplyr [dupliquer]


Cette question a déjà une réponse ici:

J'ai un dataframe qui ressemble à ceci

> 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

Je voudrais créer une nouvelle colonne bars_by_foo qui est la concaténation des valeurs de bar par foo. Les nouvelles données devraient donc ressembler à ceci:

  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

J'espérais que les éléments suivants fonctionneraient:

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

Mais ce code me donne une erreur

Error: incompatible types, expecting a character vector.

Qu'est-ce que je fais mal?


16
2017-07-21 21:54


origine


Réponses:


Vous pourriez simplement faire

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

Sans fonctions d'assistance


32
2017-07-21 22:25



Il semble qu’il y ait un problème avec le mutate fonction - j'ai trouvé que c'est une meilleure approche pour travailler avec summarise lorsque vous regroupez des données dans dplyr (ce n'est pas une règle difficile).

paste fonction introduit également des espaces dans le résultat soit ensemble sep = 0 ou utiliser juste utiliser paste0.

Voici mon code:

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)

Résultant en..

  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
2017-07-21 22:13



Vous pouvez essayer ceci:

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

1
2017-07-21 22:11



Votre fonction fonctionne si vous vous assurez que la barre est composée de tous les caractères et non des niveaux d'un facteur.

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

0
2017-07-21 22:14