重塑R中的一组列的多个副本Wide>长和长>宽

时间:2017-10-18 10:19:44

标签: r dplyr reshape

我从STATA转换为R. 我正在努力复制的一件事是STATA中的重塑功能。 在STATA中大致可以这样做:

reshape wide variable names, i(Unique person ID) j(ID identifying each entry per unique ID i)

我有一个包含患者使用的静脉内线的数据集(现已附上样本)。数据目前为Long(每行1行)。对于每一行,您将看到有几列;线型,插入日期,删除日期等。

我想了解如何最好地将布局1重新整形为宽幅,将布局2重新整形为长整数。每位患者都有一个唯一的ID。我可以用每个人的每一行标记一个唯一的ID(即ID_Var 1:n中的数字行)。下面的宽/长期望布局示例。

Theoretical Long and Wide Dataset layout

这与我在Stackoverflow上看到的重塑的例子(在dplyr cheatsheet中描述)有所不同 - 因为通常它们会根据行列中的值进行重新整形 - 而你会创建一个新列调用外设并从插入的值中获取值并将其放入外围列中,并将另一列称为Hickman,并将插入的值放入该列等。 典型的DPLYR示例(此处不是目标)

DPLYR type examples

我为基础或dplyr(或替代)解决方案感到高兴.... 我试过在R :: base中使用reshape并看看在dplyr中的传播但是无法工作?因为我试图在一步中完成所有这一切(这就是什么我会在STATA中做。)

例如我试过

lines_wide <- reshape(lines,idvar=lines$Episode,timevar=lines$n,direction="wide")

但我明白了: [.data.frame(data ,, idvar)中的错误:选择了未定义的列

我还尝试使用v.names指定要重新整形的特定元素:

lines_wide <- reshape(lines,idvar=lines$Episode,timevar=lines$n,direction="wide", v.names = list(lines$Site,lines$Line.Type,lines$Removal.Reason))

但我得到同样的错误。

长数据集的一个示例如下: https://www.dropbox.com/s/h0lo910ix304qj3/reshape_example.xlsx?dl=0

1 个答案:

答案 0 :(得分:2)

你真的应该提供至少你的数据...无论如何,这里是一个tidyverse - 解决方案,使用tidyrdplyr

library(tidyverse)

df <- tribble(~patient, ~line, ~inserted, ~complications,
          1,"peripheral", "01/02/17", "none",
          1,"peripheral", "04/02/17", "blocked")

# this prefix preserves the order of your variables:
names(df)[-1] <- c("[1]line", "[2]inserted", "[3]complications")

df_wide <- 
  df %>% 
  group_by(patient) %>% 
  mutate(nr = seq_len(n())) %>% # number of observations for each patient
  gather(key = key, value = value, -patient, -nr) %>% # make Long
  arrange(nr, key) %>% # sort by nr and variable name to keep you order
  unite(key, nr, key, sep = ".") %>% # paste variable number and variable name
  mutate(key = factor(key, levels = unique(key))) %>% # tells spread to preserve order
  spread(key = key, value = value) # make wide again

# remove the prefix from above
names(df_wide) <- names(df_wide) %>% 
               gsub(pattern = "\\[\\d{1}\\]", 
               replacement = "")

df_wide

  patient   `1.line` `1.inserted` `1.complications`   `2.line` `2.inserted` `2.complications`
*   <dbl>      <chr>        <chr>             <chr>      <chr>        <chr>             <chr>
1       1 peripheral     01/02/17              none peripheral     04/02/17           blocked

反之亦然:

df_long <- 
  df_wide %>%
  gather(key = key, value = value, -patient) %>% 
  separate(key, into = c("nr", "key")) %>% 
  spread(key = key, value = value) %>% 
  select(patient, line, inserted, complications)

df_long

  patient       line inserted complications
*   <dbl>      <chr>    <chr>         <chr>
1       1 peripheral 01/02/17          none
2       1 peripheral 04/02/17       blocked