重塑 R 中一组列的多个副本,包括 Wide > Long 和 Long > Wide

Reshape multiple copies of a set of columns in R both Wide > Long and Long > Wide

我正在从 STATA 转换为 R。 我努力很好地复制的一件事是 STATA 中的重塑功能。 在 STATA 中,大致可以通过以下方式完成:

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

我有一个数据集,其中包含患者使用的 intra-venous 行(样本现已附上)。数据目前是长行(每行 1 行)。对于每一行,您会看到有几列; line-type、插入日期、删除日期等

我想了解如何最好地将布局 1 重塑为宽,将布局 2 重塑为长。每个患者都有一个唯一的 ID。我可以用唯一 ID 标记每个人的每一行(即 ID_Var 1:n 内的行数)。下面是宽/长所需布局的示例。

这与我在 Whosebug 上看到的重塑示例(在 dplyr 备忘单中有所描述)感觉不同 - 因为通常它们会根据行列中的值进行重塑 - 而你会制作一个名为 peripheral 的新列,并从插入的值中获取值并将其放入 peripheral 列中,然后制作另一个名为 Hickman 的列,并将插入的值放入该列等。 典型的 DPLYR 例子(不是这里的目标)

我很高兴有一个基本或 dplyr(或者实际上是替代)解决方案.... 我试过在 R::base 中使用 reshape 并查看了 dplyr 中的 spread 但两者都无法正常工作?因为我试图在 1 个步骤中完成所有操作(这就是我在 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

你真的应该至少提供你的数据...无论如何,这里有一个 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