2017-05-15 2 views
-2

Je voudrais calculer le nombre x unique pour la division de la colonne x par '|' et la sous-chaîne gauche 2 caractères dans R.Comptage unique pour une colonne - séparation par délimiteur et comptage unique pour la sous-chaîne

df <-data.frame(id = c(11,22,33,44), 
       x = c(NA,'cna|cnb|jpa|usa|jpb|usb','kra|krb|kru|usb|usa','jpa|jpu|epa|epb|usa|woa|cna|jpu')) 

> df 
    id        x 
1 11       <NA> 
2 22   cna|cnb|jpa|usa|jpb|usb 
3 33    kra|krb|kru|usb|usa 
4 44 jpa|jpu|epa|epb|usa|woa|cna|jpu 

Je veux obtenir ci-dessous.

id count 
1 11 0 
2 22 3 
3 33 2   
4 44 5 
  • ligne 1 est 0
  • ligne 2 est CN, JP, US (3 données)
  • ligne 3 est kr, US (2 données)
  • ligne 4 est jp, ep , us, wo, cn (5 données)

Répondre

1

Nous pouvons utiliser tidyverse. Nous divisons les éléments en 'x' et étendons au format long avec separate_rows, mutate le 'x' en prenant seulement les deux premiers caractères (substr), regroupés par 'id', trouver le count des éléments non-NA uniques en utilisant n_distinct

library(tidyverse) 
df %>% 
    separate_rows(x) %>% 
    mutate(x= substr(x, 1, 2)) %>% 
    group_by(id) %>% 
    summarise(count = n_distinct(x[!is.na(x)])) 
# A tibble: 4 x 2 
#  id count 
# <dbl> <int> 
#1 11  0 
#2 22  3 
#3 33  2 
#4 44  5 
+1

wow! c'est génial! merci ~ – user3317871

+0

@ utilisateur3317871 Merci. Vous pouvez également vérifier [ici] (http://stackoverflow.com/help/someone-answers) – akrun

2

Voici une autre approche. Il est pas aussi compact et simple que la réponse de akrun, mais il ne dépend pas des bibliothèques:

df$count <- sapply(df$x, function(varx){ 
    strs <- unique(sapply(unlist(strsplit(varx, "|", fixed = T)), function(string){ 
     substr(string, 1, 2) 
    })) 
    length(strs[!is.na(strs)]) 
}) 

Sortie:

id        x count 
1 11       <NA>  0 
2 22   cna|cnb|jpa|usa|jpb|usb  3 
3 33    kra|krb|kru|usb|usa  2 
4 44 jpa|jpu|epa|epb|usa|woa|cna|jpu  5 
+1

Un peu plus court: 'spply (spply (strsplit (as.character (df $ x), '\\ |'), substr, start = 1, stop = 2), fonction (x) length (unique (na.omit (x)))) ' – Jaap

+1

@Jaap, un peu plus court (un de moins) serait' sapply (strsplit (comme .character (df $ x), "|", fixé = TRUE), longueur de la fonction (x) (unique (substr (na.omit (x), 1, 2)))) ' –

+0

great ~! La solution est si simple! Merci beaucoup! – user3317871