1

次のようなデータフレームがあります。

message.id,sender,recipients
1,A,B|C
2,A,B
3,B,C|D|Q

recipients「|」で列を分割したい 次に、結果を収集してこれを生成します。

message.id,sender,recipient
1,A,B
1,A,C
2,A,B
3,B,C
3,B,D
3,B,Q

この操作を達成するためのより明確な方法は何ですか? これが私の現在のコードです:

library(dplyr)
library(stringr)
library(tidyr)

df <- data.frame(message.id = c(1,2,3),
                 sender = c("A","A","B"),
                 recipients = c("B|C","B","C|D|Q"))

max.splits = df$recipients %>% str_count("\\|") %>% max + 1

df %>% separate(recipients,1:max.splits, sep = "\\|") %>%
  gather(trash,recipient,-message.id,-sender) %>%
  select(message.id, sender, recipient) %>%
  filter(recipient %>% is.na == FALSE) %>%
  arrange(message.id)
4

4 に答える 4

3

私は偏っていますがcSplit、「splitstackshape」パッケージから提案します。

使用方法は次のとおりです。

library(splitstackshape)
cSplit(df, "recipients", "|", "long")
#    message.id sender recipients
# 1:          1      A          B
# 2:          1      A          C
# 3:          2      A          B
# 4:          3      B          C
# 5:          3      B          D
# 6:          3      B          Q

または、配管には「dplyr」を、パイプには「tidyr」を組み合わせて使用​​すると、次のunnestように試すことができます。

library(dplyr)
library(tidyr)
df %>%
  mutate(recipients = as.character(recipients)) %>%         ## need character for strsplit
  mutate(recipients = strsplit(recipients, "|", TRUE)) %>%  ## Use `fixed = TRUE`
  unnest(recipients)                                        ## `unnest` goes to long form
# Source: local data frame [6 x 3]
# 
#   message.id sender recipients
#        (dbl) (fctr)      (chr)
# 1          1      A          B
# 2          1      A          C
# 3          2      A          B
# 4          3      B          C
# 5          3      B          D
# 6          3      B          Q
于 2015-12-30T07:10:00.943 に答える
1

dplyrとを使用したソリューションを次に示します。tidyr

df <- data.frame(message.id = 1:3, sender = c("A","A","B"),
recipients = c("B|C","B","C|D|Q"))

元データ

  message.id sender recipients
1          1      A        B|C
2          2      A          B
3          3      B      C|D|Q

コード

df %>% separate(recipients,into =c("r1","r2","r3")) %>% 
gather("sen","recipient",r1:r3) %>% select(-sen) %>% 
filter(!is.na(recipient))

結果

  message.id sender recipient
1          1      A         B
2          2      A         B
3          3      B         C
4          1      A         C
5          3      B         D
6          3      B         Q
于 2015-12-30T07:32:56.137 に答える
1

使用できますdata.table

library(data.table)
setDT(df)[, list(recipient=unlist(strsplit(recipients, '[|]'))),
              .(message.id, sender)]
于 2015-12-30T06:06:42.013 に答える