R

时间:2018-10-23 15:46:45

标签: r function dataframe missing-data imputation

我正在尝试在R中构建一个函数,在该函数中,我可以根据一些规范对原始数据帧进行子集化,然后将该子集数据帧转换为比例表。

不幸的是,对于某些我没有数据的特定规范,其中一些子设置会产生一个空的数据框。因此无法计算比例表。因此,我想做的是采取最接近的时间步长,从中我获得一个非空的子集数据帧,并将其用作空的子集数据帧的输入。

以下是对我的数据框和功能的一些见解:

我的原始数据框看起来像+/-,如下所示:

| year | quarter | area | time_comb | no_individuals | lenCls | age |
|------|---------|------|-----------|----------------|--------|-----|
| 2005 | 1       | 24   | 2005.1.24 | 8              | 380    | 3   |
| 2005 | 2       | 24   | 2005.2.24 | 4              | 490    | 2   |
| 2005 | 1       | 24   | 2005.1.24 | 3              | 460    | 6   |
| 2005 | 1       | 21   | 2005.1.21 | 25             | 400    | 2   |
| 2005 | 2       | 24   | 2005.2.24 | 1              | 680    | 6   |
| 2005 | 2       | 21   | 2005.2.21 | 2              | 620    | 5   |
| 2005 | 3       | 21   | 2005.3.21 | NA             | NA     | NA  |
| 2005 | 1       | 21   | 2005.1.21 | 1              | 510    | 5   |
| 2005 | 1       | 24   | 2005.1.24 | 1              | 670    | 4   |
| 2006 | 1       | 22   | 2006.1.22 | 2              | 750    | 4   |
| 2006 | 4       | 24   | 2006.4.24 | 1              | 660    | 8   |
| 2006 | 2       | 24   | 2006.2.24 | 8              | 540    | 3   |
| 2006 | 2       | 24   | 2006.2.24 | 4              | 560    | 3   |
| 2006 | 1       | 22   | 2006.1.22 | 2              | 250    | 2   |
| 2006 | 3       | 22   | 2006.3.22 | 1              | 520    | 2   |
| 2006 | 2       | 24   | 2006.2.24 | 1              | 500    | 2   |
| 2006 | 2       | 22   | 2006.2.22 | NA             | NA     | NA  |
| 2006 | 2       | 21   | 2006.2.21 | 3              | 480    | 2   |
| 2006 | 1       | 24   | 2006.1.24 | 1              | 640    | 5   |
| 2007 | 4       | 21   | 2007.4.21 | 2              | 620    | 3   |
| 2007 | 2       | 21   | 2007.2.21 | 1              | 430    | 3   |
| 2007 | 4       | 22   | 2007.4.22 | 14             | 410    | 2   |
| 2007 | 1       | 24   | 2007.1.24 | NA             | NA     | NA  |
| 2007 | 2       | 24   | 2007.2.24 | NA             | NA     | NA  |
| 2007 | 3       | 24   | 2007.3.22 | NA             | NA     | NA  |
| 2007 | 4       | 24   | 2007.4.24 | NA             | NA     | NA  |
| 2007 | 3       | 21   | 2007.3.21 | 1              | 560    | 4   |
| 2007 | 1       | 21   | 2007.1.21 | 7              | 300    | 3   |
| 2007 | 3       | 23   | 2007.3.23 | 1              | 640    | 5   |

此处季度区域是指特定时间(年份和季度)和X编号不适用的区域。测量的个人人数( no_individuals )。例如,从第一行中我们可以得出,在2005年第一季度的24区中,我有8个个体,这些个体属于380 mm的长度等级( lenCLs ),年龄为3岁。值得一提的是,对于特定的年份,季度和区域组合,我可以使用不同的长度级别和年龄(因此,多行)!

因此,我要做的基本上是将特定年份,季度和面积组合的原始数据框子集化,然后从该组合中根据每个长度类别中的个体数量来计算比例表。

到目前为止,我的基本功能如下:

LAK <- function(df,  Year="2005", Quarter="1", Area="22", alkplot=T){
  require(FSA)

  # subset alk by year, quarter and area 
  sALK <- subset(df, year==Year & quarter==Quarter & area==Area)
  dfexp <- sALK[rep(seq(nrow(sALK)), sALK$no_individuals), 1:ncol(sALK)]
  raw <- t(table(dfexp$lenCls, dfexp$age))
  key <- round(prop.table(raw, margin=1), 3)
  return(key)

  if(alkplot==TRUE){
    alkPlot(key,"area",xlab="Age")
  }
}

从上面的数据集示例中,我们可以注意到,对于 year = 2005&Quarter = 3&area = 21 ,我没有任何可衡量的个体。但是,对于同一区域 AND 年,我有第1季度或第2季度的数据。最合理的假设是从最近的时间步中获取子集数据帧(第2季度的相同区域和年),然后从“ no_individuals ”,“ lenCls ”和“ age ”列中替换NA。

还请注意,在某些情况下,我没有特定年份的数据!在上面的示例中,可以通过查看2007年的区域24来看到这一点。在这种情况下,我不能借用最近一个季度的信息,而需要借用上一年的信息。这意味着对于 year = 2007&area = 24&Quarter = 1 ,我会借用 year = 2006&area = 24&Quarter 1 的信息,依此类推等等。

我试图通过指定一些额外的规则将其包含在我的函数中,但是由于我的编程技巧很差,所以我没有取得任何进展。

因此,这里的任何帮助将非常

这是我要更新的LAK函数:

LAK <- function(df,  Year="2005", Quarter="1", Area="22", alkplot=T){
      require(FSA)

      # subset alk by year, quarter and area 
      sALK <- subset(df, year==Year & quarter==Quarter & area==Area)

     # In case of empty dataset 
     #if(is.data.frame(sALK) && nrow(sALK)==0){

     if(sALK[rowSums(is.na(sALK)) > 0,]){
     warning("Empty subset combination; data will be subsetted based on the 
     nearest timestep combination") 

     FIXME: INCLDUE IMPUTATION RULES HERE

      }

      dfexp <- sALK[rep(seq(nrow(sALK)), sALK$no_individuals), 1:ncol(sALK)]
      raw <- t(table(dfexp$lenCls, dfexp$age))
      key <- round(prop.table(raw, margin=1), 3)
      return(key)

      if(alkplot==TRUE){
        alkPlot(key,"area",xlab="Age")
      }
    }

2 个答案:

答案 0 :(得分:1)

因此,我终于想出了解决问题的部分方法,并将在此处包含我的功能,以防某些人感兴趣:

LAK <- function(df,  Year="2005", Quarter="1", Area="22",alkplot=T){

  require(FSA)

  # subset alk by year, quarter, area and species
  sALK <- subset(df, year==Year & quarter==Quarter & area==Area)
  print(sALK)

  if(nrow(sALK)==1){
    warning("Empty subset combination; data has been subsetted to the nearest input combination") 
    syear <- unique(as.numeric(as.character(sALK$year)))
    sarea <- unique(as.numeric(as.character(sALK$area)))

    sALK2 <- subset(df, year==syear & area==sarea)
    vals <- as.data.frame(table(sALK2$comb_index))
    colnames(vals)[1] <- "comb_index" 

    idx <- which(vals$Freq>1)
    quarterId <- as.numeric(as.character(vals[idx,"comb_index"]))

    imput <- subset(df,year==syear & area==sarea & comb_index==quarterId)  
    dfexp2 <- imput[rep(seq(nrow(imput)), imput$no_at_length_age), 1:ncol(imput)]
    raw2 <- t(table(dfexp2$lenCls, dfexp2$age))
    key2 <- round(prop.table(raw2, margin=1), 3)
    print(key2)

    if(alkplot==TRUE){
      alkPlot(key2,"area",xlab="Age")
    }

  }  else {
    dfexp <- sALK[rep(seq(nrow(sALK)), sALK$no_at_length_age), 1:ncol(sALK)]
    raw <- t(table(dfexp$lenCls, dfexp$age))
    key <- round(prop.table(raw, margin=1), 3)  
    print(key)

    if(alkplot==TRUE){
      alkPlot(key,"area",xlab="Age")
    }
  }

}

当我有至少一个特定的Year&Area组合的四分之一的数据时,这解决了我的问题。但是,当我没有特定年份和地区组合的数据时,我仍在努力寻找处理方法。在这种情况下,我需要从最近的年份借用数据,该数据包含同一区域所有季度的数据。 对于上面暴露的示例,这意味着对于year = 2007&area = 24&Quarter = 1,我将借用Year = 2006&area = 24&Quarter 1的信息,依此类推。

答案 1 :(得分:0)

我不知道您是否曾经遇到过MICE,但这是一个非常酷而全面的变量插补工具。它还允许您查看估算数据的分布方式,以便选择最适合您的问题的方法。选中this brief explanationthe original package description