如何使用 reshape2 的 dcast 到 select 几个观察值(值)中的一个
How to use reshape2's dcast to select only one of several observations(values)
我有以下数据集
> dataset2
ID ATCcode date
1 1 N06AA 2001-01-01
2 1 N06AB 2001-04-01
3 1 N06AB 2001-03-01
4 1 N06AB 2001-02-01
5 1 N06AC 2001-01-01
6 2 N06AA 2001-01-01
7 2 N06AA 2001-02-01
8 2 N06AA 2001-03-01
9 3 N06AB 2001-01-01
10 4 N06AA 2001-02-01
11 4 N06AB 2001-03-01
它是长格式的,我希望它是宽格式的。但是,我只想要每个 ATCcode 的最早日期 - 而不是任何较晚的日期。因此我想在这里结束:
> datasetLong
ID N06AA N06AB N06AC
1 1 2001-01-01 2001-02-01 2001-01-01
2 2 2001-01-01 <NA> <NA>
3 3 <NA> 2001-01-01 <NA>
4 4 2001-02-01 2001-03-01 <NA>
(这只是真实数据集的一个样本,它的值和观察值比这有更多的变化)。
我已经设法对数据集进行了一些转换,但不是我想要的方式:
dataset3 <- reshape2::dcast(dataset2, ID ~ ATCcode)
给我每个 vector/list:
的长度
> dataset3
ID N06AA N06AB N06AC
1 1 1 3 1
2 2 3 0 0
3 3 0 1 0
4 4 1 1 0
我只想要一个值而不是长度,并且该值应该是最小值(或者,最早的日期)。
我在 Whosebug 上发现了一个类似的问题,但我无法以任何方式使用它而不会出现各种错误。我没有在上述尝试中使用 melt ,这可能是必要的吗?
感谢任何帮助。
此答案使用 tidyverse
方法。
一种方法是 select 每个 ID
和 ATCcode
的最小日期并将数据转换为宽格式。
library(dplyr)
df %>%
mutate(date = as.Date(date)) %>%
group_by(ID, ATCcode) %>%
slice(which.min(date)) %>%
tidyr::pivot_wider(names_from = ATCcode, values_from = date)
# ID N06AA N06AB N06AC
# <int> <date> <date> <date>
#1 1 2001-01-01 2001-02-01 2001-01-01
#2 2 2001-01-01 NA NA
#3 3 NA 2001-01-01 NA
#4 4 2001-02-01 2001-03-01 NA
数据
df <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L,
4L), ATCcode = structure(c(1L, 2L, 2L, 2L, 3L, 1L, 1L, 1L, 2L,
1L, 2L), .Label = c("N06AA", "N06AB", "N06AC"), class = "factor"),
date = structure(c(1L, 4L, 3L, 2L, 1L, 1L, 2L, 3L, 1L, 2L,
3L), .Label = c("2001-01-01", "2001-02-01", "2001-03-01",
"2001-04-01"), class = "factor")), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11"))
我有以下数据集
> dataset2
ID ATCcode date
1 1 N06AA 2001-01-01
2 1 N06AB 2001-04-01
3 1 N06AB 2001-03-01
4 1 N06AB 2001-02-01
5 1 N06AC 2001-01-01
6 2 N06AA 2001-01-01
7 2 N06AA 2001-02-01
8 2 N06AA 2001-03-01
9 3 N06AB 2001-01-01
10 4 N06AA 2001-02-01
11 4 N06AB 2001-03-01
它是长格式的,我希望它是宽格式的。但是,我只想要每个 ATCcode 的最早日期 - 而不是任何较晚的日期。因此我想在这里结束:
> datasetLong
ID N06AA N06AB N06AC
1 1 2001-01-01 2001-02-01 2001-01-01
2 2 2001-01-01 <NA> <NA>
3 3 <NA> 2001-01-01 <NA>
4 4 2001-02-01 2001-03-01 <NA>
(这只是真实数据集的一个样本,它的值和观察值比这有更多的变化)。
我已经设法对数据集进行了一些转换,但不是我想要的方式:
dataset3 <- reshape2::dcast(dataset2, ID ~ ATCcode)
给我每个 vector/list:
的长度> dataset3
ID N06AA N06AB N06AC
1 1 1 3 1
2 2 3 0 0
3 3 0 1 0
4 4 1 1 0
我只想要一个值而不是长度,并且该值应该是最小值(或者,最早的日期)。
我在 Whosebug 上发现了一个类似的问题,但我无法以任何方式使用它而不会出现各种错误。我没有在上述尝试中使用 melt ,这可能是必要的吗? 感谢任何帮助。
此答案使用 tidyverse
方法。
一种方法是 select 每个 ID
和 ATCcode
的最小日期并将数据转换为宽格式。
library(dplyr)
df %>%
mutate(date = as.Date(date)) %>%
group_by(ID, ATCcode) %>%
slice(which.min(date)) %>%
tidyr::pivot_wider(names_from = ATCcode, values_from = date)
# ID N06AA N06AB N06AC
# <int> <date> <date> <date>
#1 1 2001-01-01 2001-02-01 2001-01-01
#2 2 2001-01-01 NA NA
#3 3 NA 2001-01-01 NA
#4 4 2001-02-01 2001-03-01 NA
数据
df <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L,
4L), ATCcode = structure(c(1L, 2L, 2L, 2L, 3L, 1L, 1L, 1L, 2L,
1L, 2L), .Label = c("N06AA", "N06AB", "N06AC"), class = "factor"),
date = structure(c(1L, 4L, 3L, 2L, 1L, 1L, 2L, 3L, 1L, 2L,
3L), .Label = c("2001-01-01", "2001-02-01", "2001-03-01",
"2001-04-01"), class = "factor")), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11"))