【问题标题】:R extremely long to wide with linked rowsR 非常长到宽,有链接的行
【发布时间】:2022-11-23 14:34:30
【问题描述】:

我有一个类似于以下的 df:

df <- data.frame(name = c("billy","billy","sarah","sarah","sarah","sarah","sarah","sarah","sarah","linda","linda","linda","linda","linda","linda"),
                 data = c("soccer","8-01-1992","basketball","soccer","10-19-1995","10-25-1995","basketball","11-24-1995",6,"hockey","soccer","basketball","12-21-2001","12-30-2001","1-19-2002"),
                 event = c("joins.project","joins.when","joins.project","joins.project1","joins.when","joins.when1","participation.project","participation.when","participation.repetitions","joins.project","joins.project1","joins.project2","joins.when","joins.when1","joins.when2"))

> df
    name       data                     event
1  billy     soccer             joins.project
2  billy  8-01-1992                joins.when
3  sarah basketball             joins.project
4  sarah     soccer            joins.project1
5  sarah 10-19-1995                joins.when
6  sarah 10-25-1995               joins.when1
7  sarah basketball     participation.project
8  sarah 11-24-1995        participation.when
9  sarah          6 participation.repetitions
10 linda     hockey             joins.project
11 linda     soccer            joins.project1
12 linda basketball            joins.project2
13 linda 12-21-2001                joins.when
14 linda 12-30-2001               joins.when1
15 linda  1-19-2002               joins.when2

我想要的输出如下。

new_df <- data.frame(name = c("billy", "sarah", "sarah", "sarah", "linda", "linda", "linda"),
                     join_or_particip = c("join", "join", "join", "participate", "join", "join", "join"),
                     sport = c("soccer", "basketball", "soccer", "basketball", "hockey", "soccer", "basketball"),
                     when = c("8-01-1992", "10-19-1995", "10-25-1995", "11-24-1995", "12-21-2001", "12-30-2001", "1-19-2002"),
                     repetitions = c(NA, NA, NA, 6, NA, NA, NA))
new_df
   name join_or_particip      sport       when repetitions
1 billy             join     soccer  8-01-1992          NA
2 sarah             join basketball 10-19-1995          NA
3 sarah             join     soccer 10-25-1995          NA
4 sarah      participate basketball 11-24-1995           6
5 linda             join     hockey 12-21-2001          NA
6 linda             join     soccer 12-30-2001          NA
7 linda             join basketball  1-19-2002          NA

我想我需要使用 spread() 来实现这一点,但我不确定如何解释 df 中的某些行是链接的这一事实(即“joins.project1”和“joins.when1”放在一起) .进一步的上下文:这是一个数据集,包含在不同日期“加入”或“参与”1 到 200 多项“运动”的人。如果他们“参与”,则还有一个称为“重复”的附加变量(即他们参与了多少次)。

【问题讨论】:

    标签: r dplyr tidyr data-cleaning spread


    【解决方案1】:

    设计该数据结构的人与数据无关。

    library(data.table)
    setDT(df)
    df[, c("action", "type") := tstrsplit(event, "\.")]
    df[, c("type", "ID") := tstrsplit(type, "(?<=[A-Za-z])(?=[0-9])", perl = TRUE)]
    df[is.na(ID), ID := 0]
    
    res <- df[type == "project"]
    
    #data.table joins:
    res[df[type == "when"], when := i.data, on = .(name, action, ID)]
    res[df[type == "repetitions"], repetitions := i.data, on = .(name, action, ID)]
    res
    #      name       data                 event        action    type ID       when repetitions
    #  1: billy     soccer         joins.project         joins project  0  8-01-1992        <NA>
    #  2: sarah basketball         joins.project         joins project  0 10-19-1995        <NA>
    #  3: sarah     soccer        joins.project1         joins project  1 10-25-1995        <NA>
    #  4: sarah basketball participation.project participation project  0 11-24-1995           6
    #  5: linda     hockey         joins.project         joins project  0 12-21-2001        <NA>
    #  6: linda     soccer        joins.project1         joins project  1 12-30-2001        <NA>
    #  7: linda basketball        joins.project2         joins project  2  1-19-2002        <NA>
    

    【讨论】:

      【解决方案2】:

      dplyr方式

      library(dplyr)
      library(tidyr)
      library(stringr)
      
      df %>%
        separate(event, into = c("join_or_particip", "type"), sep = "\.") %>%
        mutate(num = as.numeric(gsub('[^0-9.-]', '', type)) %>% replace_na(., 0),
               type = gsub('[0-9]+', '', type)) %>%
        pivot_wider(id_cols = c(name, join_or_particip, num), names_from = type, values_from = data) %>%
        select(-num)
      
      
        name  join_or_particip project    when       repetitions
        <chr> <chr>            <chr>      <chr>      <chr>      
      1 billy joins            soccer     8-01-1992  NA         
      2 sarah joins            basketball 10-19-1995 NA         
      3 sarah joins            soccer     10-25-1995 NA         
      4 sarah participation    basketball 11-24-1995 6          
      5 linda joins            hockey     12-21-2001 NA         
      6 linda joins            soccer     12-30-2001 NA         
      7 linda joins            basketball 1-19-2002  NA 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-13
        • 2020-04-25
        • 2016-06-07
        • 2022-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多