如何使用 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 每个 IDATCcode 的最小日期并将数据转换为宽格式。

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"))