R如何在没有键值对的情况下“传播”数据

时间:2019-01-13 10:43:19

标签: r tidyr

我有数据:

rowID    incidentID participant.type
1          1                A
2          1                B
3          2                A
4          3                A
5          3                B
6          3                C
7          4                B
8          4                C

最后,我想结束

   rowID incident participant.type participant.type.1 participant.type.2
    1        1                A                  B                   
    2        2                A                                      
    3        3                A                  B                  C
    4        4                B                  C      

我尝试了传播,但每次事件都无法达到一行;我认为我没有创建键值对的方法,所以我想知道是否还有其他方法可以做到这一点。

5 个答案:

答案 0 :(得分:2)

在使用spread()之前,您需要创建一个正确的key自变量。

df %>% select(-rowID) %>%
       group_by(incidentID) %>%
       mutate(id = 1:n()) %>%
       spread(id, participant.type)

#   incidentID  `1`   `2`   `3`  
#        <int>  <fct> <fct> <fct>
# 1          1  A     B     NA   
# 2          2  A     NA    NA   
# 3          3  A     B     C    
# 4          4  B     C     NA 

答案 1 :(得分:1)

由于您的分组基于icidentID列中的行顺序。以下简单的解决方案也将起作用。

它只是过滤数据框,然后最终合并。

就有效使用计算能力而言,它可能不是最佳解决方案,但很容易理解。

library(tidyverse)

df <- 
  tribble(
    ~rowID,    ~incidentID, ~participant.type,
    1,          1,                "A",
    2,          1,                "B",
    3,          2,                "A",
    4,          3,                "A",
    5,          3,                "B",
    6,          3,                "C",
    7,          4,                "B",
    8,          4,                "C")

df_1 <- df %>%
  select(-rowID) %>% 
  group_by(incidentID) %>% 
  filter(row_number()==1)


df_2 <- df %>%
  select(-rowID) %>% 
  group_by(incidentID) %>% 
  filter(row_number()==2) %>% 
  rename(participant.type.1 = participant.type)


df_3 <- df %>%
  select(-rowID) %>% 
  group_by(incidentID) %>% 
  filter(row_number()==3) %>% 
  rename(participant.type.2 = participant.type) 

full_join(df_1, full_join(df_2, df_3))

结果:

Joining, by = "incidentID"
Joining, by = "incidentID"
# A tibble: 4 x 4
# Groups:   incidentID [?]
  incidentID participant.type participant.type.1 participant.type.2
       <dbl> <chr>            <chr>              <chr>             
1          1 A                B                  NA                
2          2 A                NA                 NA                
3          3 A                B                  C                 
4          4 B                C                  NA    

答案 2 :(得分:0)

这是我的解决方法:

df %>%
  select(-rowID) %>%
  group_by(incidentID) %>%
  nest() %>%
  mutate(data = map_chr(data, ~str_c(.x$participant.type, collapse = '_'))) %>%
  separate(data, paste0('participant.type.', 0:2)) %>%
  mutate_at(2:4, ~replace_na(.x, ''))

答案 3 :(得分:0)

为此,我们可以使用reshape2::dcast

reshape2::dcast(df, insidentID ~ participant.type)    
  #   insidentID    A    B    C
  # 1          1 <NA>    B <NA>
  # 2          8 <NA>    B <NA>
  # 3         12 <NA> <NA>    C
  # 4         16    A <NA> <NA>
  # 5         24 <NA>    B <NA>
  # 6         27 <NA>    B    C
  # 7         29 <NA> <NA>    C

与数据

set.seed(123)
df <- data.frame(insidentID = sample(0:30, 8L, replace = TRUE),
                 participant.type = sample(LETTERS[1:3], 8L, replace = TRUE),
                 stringsAsFactors = FALSE)
df
#   insidentID participant.type
# 1          8                B
# 2         24                B
# 3         12                C
# 4         27                B
# 5         29                C
# 6          1                B
# 7         16                A
# 8         27                C

答案 4 :(得分:0)

@markus提供的“相关问题”链接显示了多种其他解决方案,包括最简洁的tidyverse格式:

tickets.add(new Ticket(1L, TicketType.FirstClass));

给予:

 df %>% 
  group_by(incidentID) %>%
  mutate(rn = paste0("newcolumn",row_number()))  %>%
  spread(rn, participant.type)

A