2015-10-22 31 views
11

E-posta iletişimi içeren bir veri kümem var. Bir örnek:tidyr :: nasıl kullanılır, gerekli değişkenlerin sayısı bilinmiyor ayrı ayrı

library(dplyr) 
library(tidyr) 

dat <- data_frame('date' = Sys.time(), 
        'from' = c("[email protected]", "[email protected]", 
          "[email protected]", "[email protected]"), 
        'to' = c("[email protected],[email protected]", "[email protected]", 
          "[email protected],[email protected],[email protected]", "[email protected]")) 
bana yetiyor kaç değişkenleri görmek için yeterli basit Yukarıdaki örnekte

, bu yüzden aşağıdakileri yapın sadece olabilir: Ancak

dat %>% separate(to, into = paste0("to_", 1:3), sep = ",", extra = "merge", fill = "right") 

#Source: local data frame [4 x 5] 
# 
#     date    from    to_1    to_2    to_3 
#    (time)    (chr)    (chr)    (chr)    (chr) 
#1 2015-10-22 14:52:41 [email protected] [email protected] [email protected]    NA 
#2 2015-10-22 14:52:41 [email protected] [email protected]     NA    NA 
#3 2015-10-22 14:52:41 [email protected]  [email protected] [email protected] [email protected] 
#4 2015-10-22 14:52:41  [email protected] [email protected]     NA    NA 

, benim veri kümesi 4.000 kayıtları uzunluğunda ve ben 'İçinden kaç tane değişkene sahip olacağımı ve bunun için en fazla sayıda elemanın bulunduğu satırı bulmamaya çalışıyorum.

n_vars <- dat$to %>% str_split(",") %>% lapply(function(z) length(z)) %>% unlist() %>% max() 

Ama bu verimsiz görünmektedir: bu işleme yaklaşımım ilk sütununu kendim bölünmüş ve her bir bölünmenin uzunluğunu almak ve max bulmaktır. Bunu yapmanın daha iyi bir yolu var mı?

+0

kullanabilirsiniz kütüphane (data.table); cbind (dat, setDT (dat) [, tstrsplit (to, ",")]) ' –

+0

Başka bir paket yüklemek yerine makul bir çözüm gibi görünüyor. Eğer zaten 'tidyverse' yüklüyorsanız 'map_dbl' yi kullanabilir ve 'unlist'i kaldırarak biraz daha temiz hale getirebilirsiniz. 'Dat $ için%>% str_split ("")%>% map_dbl (~ uzunluğu (.))%>% Max()' – Tunn

cevap

6

Biz `da belki cSplit

library(splitstackshape) 
cSplit(dat, 'to', ',') 
9

Bu iyi bir soru - her zamanki repsonse da süper verimli değildir strsplit ardından unnest ve spread, kullanmaktır:

library(dplyr) 
library(tidyr) 

dat %>% mutate(to = strsplit(to, ",")) %>% 
     unnest(to) %>% 
     group_by(from) %>% 
     mutate(row = row_number()) %>% 
     spread(row, to) 

Source: local data frame [4 x 5] 

       date    from     1     2     3 
       (time)    (chr)    (chr)    (chr)    (chr) 
1 2015-10-22 15:03:17 [email protected] [email protected] [email protected]    NA 
2 2015-10-22 15:03:17 [email protected] [email protected]     NA    NA 
3 2015-10-22 15:03:17 [email protected]  [email protected] [email protected] [email protected] 
4 2015-10-22 15:03:17  [email protected] [email protected]     NA    NA 
+0

Sana sonunda yayılmamış isteğe çünkü bu, daha iyi olduğunu düşünüyorum. Tüm bu ayrı sütunlara e-postaları bölmek aptalca görünüyor. – bramtayl

+0

@bramtayl Sana bu senaryoda geniş verilere sahip mantıklı değil kabul genelindeki verilere ziyade uzun – jeremycg

+0

@bramtayl ile bitirmek kalmaz, bu zor kılan kasten ayrı bir duygu var (ve de yok Çoğu durum), ama ihtiyacınız olan yeni sütunları bilmediğinizde 'ayrı' kullanma konusunu alt etmek için başınızı saracak kolay bir kavramdı. Akrun'un çözümü hala iyi bir şey çünkü bir yöndeki tüm e-postaları almak için yön = "uzun". – brittenb