change a column from birth date to age in r

后端 未结 7 2059
灰色年华
灰色年华 2020-12-09 17:36

I am using data.table for the first time.

I have a column of about 400,000 ages in my table. I need to convert them from birth dates to ages.

What is the bes

7条回答
  •  [愿得一人]
    2020-12-09 18:02

    I wasn't happy with any of the responses when it comes to calculating the age in months or years, when dealing with leap years, so this is my function using the lubridate package.

    Basically, it slices the interval between from and to into (up to) yearly chunks, and then adjusts the interval for whether that chunk is leap year or not. The total interval is the sum of the age of each chunk.

    library(lubridate)
    
    #' Get Age of Date relative to Another Date
    #'
    #' @param from,to the date or dates to consider
    #' @param units the units to consider
    #' @param floor logical as to whether to floor the result
    #' @param simple logical as to whether to do a simple calculation, a simple calculation doesn't account for leap year.
    #' @author Nicholas Hamilton
    #' @export
    age <- function(from, to = today(), units = "years", floor = FALSE, simple = FALSE) {
    
      #Account for Leap Year if Working in Months and Years
      if(!simple && length(grep("^(month|year)",units)) > 0){
        df = data.frame(from,to)
        calc = sapply(1:nrow(df),function(r){
    
          #Start and Finish Points
          st = df[r,1]; fn = df[r,2]
    
          #If there is no difference, age is zero
          if(st == fn){ return(0) }
    
          #If there is a difference, age is not zero and needs to be calculated
          sign = +1 #Age Direction
          if(st > fn){ tmp = st; st = fn; fn = tmp; sign = -1 } #Swap and Change sign
    
          #Determine the slice-points
          mid   = ceiling_date(seq(st,fn,by='year'),'year')
    
          #Build the sequence
          dates = unique( c(st,mid,fn) )
          dates = dates[which(dates >= st & dates <= fn)]
    
          #Determine the age of the chunks
          chunks = sapply(head(seq_along(dates),-1),function(ix){
            k = 365/( 365 + leap_year(dates[ix]) )
            k*interval( dates[ix], dates[ix+1] ) / duration(num = 1, units = units)
          })
    
          #Sum the Chunks, and account for direction
          sign*sum(chunks)
        })
    
      #If Simple Calculation or Not Months or Not years
      }else{
        calc = interval(from,to) / duration(num = 1, units = units)
      }
    
      if (floor) calc = as.integer(floor(calc))
      calc
    }
    

提交回复
热议问题