重塑 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
解决方案,使用 tidyr
和 dplyr
:
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
我正在从 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
解决方案,使用 tidyr
和 dplyr
:
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