根据数据框名称计算多个数据框的使用期限

我想知道这里有人可以帮助我解决lapply问题。

每个月都会提取数据,并根据提取的日期(01-08-201901-09-201901-10-2019等来命名数据帧)。每个数据帧的内容类似于以下示例:

01-09-2019

ID   DOB 
3    01-07-2019
5    01-06-2019
7    01-05-2019
8    01-09-2019

01-10-2019

ID   DOB 
2    01-10-2019
5    01-06-2019
8    01-09-2019
9    01-02-2019

随着月份的推移,正在下载更多的数据集。

我想基于提取数据的日期来计算每个数据集中的人的年龄-因此,实质上,年龄就是数据框名称与DOB之间的日期差变量。

01-09-2019

ID   DOB          AGE(months)
3    01-07-2019   2
5    01-06-2019   3
7    01-05-2019   4
8    01-09-2019   0

01-10-2019

ID   DOB          AGE(months)
2    01-10-2019   0   
5    01-06-2019   4
8    01-09-2019   1
9    01-02-2019   8

我当时正在考虑将所有数据帧放到一个列表中(有很多),然后使用lapply计算所有数据帧的使用期限。如何计算数据框名称和列之间的差异?

huzhanyuan09 回答:根据数据框名称计算多个数据框的使用期限

如果我建议使用稍微不同的方法:在计算年龄之前将列表压缩到单个数据框中可能更有意义。鉴于您的数据看起来像这样,即它是一个数据帧列表,其中列表元素名称是访问日期:

$`01-09-2019`
# A tibble: 4 x 2
     ID DOB       
  <dbl> <date>    
1     3 2019-07-01
2     5 2019-06-01
3     7 2019-05-01
4     8 2019-09-01

$`01-10-2019`
# A tibble: 4 x 2
     ID DOB       
  <dbl> <date>    
1     2 2019-10-01
2     5 2019-06-01
3     8 2019-09-01
4     9 2019-02-01

您可以先使用参数bind_rows调用.id = "date_extracted",以将列表变成数据框,然后以月为单位计算年龄。

library(tidyverse)
library(lubridate)

tib <- bind_rows(tib_list,.id = "date_extracted") %>% 
    mutate(date_extracted = dmy(date_extracted),DOB = dmy(DOB),age_months = month(date_extracted) - month(DOB)
           )

#### OUTPUT ####
# A tibble: 8 x 4
  date_extracted    ID DOB        age_months
  <date>         <dbl> <date>          <dbl>
1 2019-09-01         3 2019-07-01          2
2 2019-09-01         5 2019-06-01          3
3 2019-09-01         7 2019-05-01          4
4 2019-09-01         8 2019-09-01          0
5 2019-10-01         2 2019-10-01          0
6 2019-10-01         5 2019-06-01          4
7 2019-10-01         8 2019-09-01          1
8 2019-10-01         9 2019-02-01          8
,

这也可以用lapply解决,但是在这种情况下,我们也可以使用Map在列表中添加所有数据帧之后遍历列表及其名称。在基数R中,

Map(function(x,y) {
 x$DOB <- as.Date(x$DOB)
 transform(x,age = as.integer(format(as.Date(y),"%m")) - 
                    as.integer(format(x$DOB,"%m")))
},list_df,names(list_df))


#$`01-09-2019`
#  ID        DOB age
#1  3 0001-07-20   2
#2  5 0001-06-20   3
#3  7 0001-05-20   4
#4  8 0001-09-20   0

#$`01-10-2019`
#  ID        DOB age
#1  2 0001-10-20   0
#2  5 0001-06-20   4
#3  8 0001-09-20   1
#4  9 0001-02-20   8

我们也可以在tidyverse

中进行相同的操作
library(dplyr)
library(lubridate)

purrr::imap(list_df,~.x %>% mutate(age = month(.y) - month(DOB)))

数据

list_df <- list(`01-09-2019` = structure(list(ID = c(3L,5L,7L,8L),DOB = structure(c(3L,2L,1L,4L),.Label = c("01-05-2019","01-06-2019","01-07-2019","01-09-2019"),class = "factor")),class = "data.frame",row.names = c(NA,-4L)),`01-10-2019` = structure(list(ID = c(2L,8L,9L),DOB = structure(c(4L,3L,1L),.Label = c("01-02-2019","01-09-2019","01-10-2019"),-4L)))
,

使用日期和数字作为数据框名称是一种不好的做法,如下所示,在此基本R解决方案中显示为“ x”:

df_list <- list(x01_09_2019 = `01-09-2019`,x01_10_2019 = `01-10-2019`)

df_list <- mapply(cbind,"report_date" = names(df_list),df_list,SIMPLIFY = F)

df_list <- lapply(df_list,function(x){

  x$report_date <- as.Date(gsub("_","-",gsub("x","",x$report_date)),"%d-%m-%Y")

  x$Age <- x$report_date - x$DOB

  return(x)

  }

)

数据:

`01-09-2019` <- structure(list(ID = c(3,5,7,8),DOB = structure(c(18078,18048,18017,18140),class = "Date")),-4L))

`01-10-2019` <- structure(list(ID = c(2,8,9),DOB = structure(c(18170,18140,17928),-4L))
本文链接:https://www.f2er.com/3162538.html

大家都在问