【问题标题】:How to change BIG dataframe format: patients with 2 visits and multiple variables for each visit如何更改 BIG 数据框格式:患者有 2 次就诊,每次就诊有多个变量
【发布时间】:2019-11-02 14:13:11
【问题描述】:

我有一个大型数据框(800 个变量的 15000 个观察值)。观察结果是 2 个不同时间点的患者(即 15000 obs = 10000 基线访问的患者 + 前 10000 名返回进行随访的 5000 名患者)。患者有一个患者 ID 变量(PtID:具有 10000 个水平的因子)和一个访问变量(访问:具有 2 个水平的因子:1 为基线,2 为随访)。

数据示例

    PtID Visit Age_Visit Brain_colour    BP       .................
     40    1        60         NA        130 
     40    2        62         blue      120
     70    1        50         green     145
     101   1        67         red       67
     263   1        78         red       178
     263   2        80         green     90
     143   1        15         blue      123
     219   1        69         red       110
     219   2        70         green     NA

我想更改数据框的格式,以便每个患者都是一个单一的观察结果,其中 800 个基线变量作为不同的后续变量重复(从 800 个变量的 15000 个 obs 到 10000 个 obs(仅限基线患者) ) 的 1600 个变量)。没有随访的 5000 名患者将具有所有随访变量的 NA 值。

我从另一个问题中找到了以下代码,但有太多变量需要更改,我无法将它们全部列出。

 d <- setDT(x)[, list(WorryHighBGNow = paste(WorryHighBGNow, 
 collapse = ', ')),by = c('PtID')] 

另外我想创建新的后续变量。对于这么大的数据框,我怎样才能轻松地将上面的数据更改为下面的数据?

     PtID Age_Visit1 Age_Visit2 Brain_colour1 Brain_colour2  BP1       BP2       .................
     40      60       62          NA          blue           120       145 
     70      50       NA          green        NA            145       NA
     101     67       NA          red          NA             67       NA
     263     78       80          red         green          178       90
     ...................

【问题讨论】:

    标签: r dataframe format rstudio


    【解决方案1】:
    library(tidyverse)
    df %>%
      gather(col, val, -c(PtID, Visit)) %>%
      unite("col2", c("col", "Visit")) %>%
      spread(col2, val)
    
      PtID Age_Visit_1 Age_Visit_2 BP_1 BP_2 Brain_colour_1 Brain_colour_2
    1   40          60          62  130  120           <NA>           blue
    2   70          50        <NA>  145 <NA>          green           <NA>
    3  101          67        <NA>   67 <NA>            red           <NA>
    4  143          15        <NA>  123 <NA>           blue           <NA>
    5  219          69          70  110 <NA>            red          green
    6  263          78          80  178   90            red          green
    

    编辑: 为了保留变量类型,一种方法是对所有字符列、所有数字列等分别执行相同的任务,然后将它们绑定在一起。

    # First collect list of all the numeric and character columns
    df_num_cols <- df %>% select_if(is.numeric) %>% names()
    df_char_cols <- df %>% select_if(is.character) %>% names()
    
    df_nums <- df %>%
      select_at(vars(c("PtID", Visit, df_num_cols))) %>%
      gather(col, val, -c(PtID, Visit)) %>%
      unite("col2", c("col", "Visit")) %>%
      spread(col2, val)
    
    df_chars <- df %>%
      select_at(vars(c("PtID", Visit, df_char_cols))) %>%
      gather(col, val, -c(PtID, Visit)) %>%
      unite("col2", c("col", "Visit")) %>%
      spread(col2, val)
    
    df2 <- bind_cols(df_nums, df_chars)
    df2 %>% str()
    
    'data.frame':   6 obs. of  8 variables:
     $ PtID          : int  40 70 101 143 219 263
     $ Age_Visit_1   : int  60 50 67 15 69 78
     $ Age_Visit_2   : int  62 NA NA NA 70 80
     $ BP_1          : int  130 145 67 123 110 178
     $ BP_2          : int  120 NA NA NA NA 90
     $ PtID1         : int  40 70 101 143 219 263
     $ Brain_colour_1: chr  NA "green" "red" "blue" ...
     $ Brain_colour_2: chr  "blue" NA NA NA ...
    

    【讨论】:

    • 然而,这已将我所有的变量(整数、因子、数字)更改为字符。我能做些什么来避免这种情况吗?
    • 是的,但我认为它会添加一些步骤来保持相同的结构。我会看看。也可能有更优雅的 data.table 方法,或者您可以使用 tidyr 的开发版本,它具有更强大的传播/收集习惯,pivot_wider/pivot_longer。
    • 我找到了一种保留数字类的方法,但由于某些原因,因素仍会转换为字符,将其发布在您的编辑下方(顺便感谢乔恩,你很棒!)
    【解决方案2】:

    将 Dataframe 从 LONG 更改为 WIDE(这将保留 NUMERIC 类,但仍会自动将所有 FACTORS 转换为 CHARACTERS):

             library(tidyr)                              
             df_wide <- df_long %>%
             gather(col, val, -c(PtID, Visit)) %>%
             unite("col2", c("col", "Visit")) %>%
             spread(col2, val, convert = TRUE)
    

    将 CHARACTERS 转换回 FACTORS:

             df_wide <- as.data.frame(unclass(df_wide))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      • 2021-02-23
      • 2013-11-16
      相关资源
      最近更新 更多