R 中空子集数据帧的数据插补
Data imputation for empty subsetted dataframes in R
我正在尝试在 R 中构建一个函数,我可以在其中根据某些规范对原始数据帧进行子集化,然后将这个子集化的数据帧转换成一个比例 table。
不幸的是,对于某些特定的规范,我没有数据,其中一些子集会产生一个空数据框;因此无法计算出比例table。所以,我想做的是从我有一个非空子集数据帧的最近时间步长开始,并将它用作空子集数据帧的输入。
以下是对我的数据框和函数的一些见解:
我的原始数据框看起来 +/- 如下:
| 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 |
这里year, quarter and area指的是特定时间(Year & Quarter ) 和 X 编号的区域。对个人进行了测量 (no_individuals)。例如,从第一行我们得到,在 2005 年第一季度,在区域 24 中,我有 8 个个体,长度 class (lenCLs) 为 380 mm年龄=3。值得一提的是,对于特定的年份、季度和区域组合,我可以有不同的长度 classes 和年龄(因此,多行)!
所以我想做的基本上是对特定年份、季度和区域组合的原始数据框进行子集化,然后根据每个长度中的个体数量从该组合中计算一个比例 table class。
到目前为止,我的基本功能如下所示:
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”和“[=37=”列中的 NA ]age”相应。
另请注意,在某些情况下,我没有特定年份的数据!在上面的示例中,可以通过查看 2007 年的区域 24 来了解这一点。在这种情况下,我无法借用最近季度的信息,而需要借用前一年的信息。这意味着对于 year=2007 & area=24 & quarter=1 我将从 year=2006 & area=24 & quarter 1[=50] 借用信息=],依此类推。
我试图通过指定一些额外的规则将其包含在我的函数中,但由于我的编程技能不佳,我没有取得任何进展。
因此,我们将非常感谢任何帮助。
这是我要更新的 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")
}
}
我不知道您是否遇到过 MICE,但它是一个非常酷且全面的变量插补工具。它还允许您查看估算数据的分布情况,以便您可以选择最适合您的问题的方法。检查 this brief explanation and the original package description
所以,我终于找到了解决我问题的部分方法,并将我的函数包含在这里以防有人感兴趣:
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 中借用数据,其中包含同一地区所有季度的数据。
对于上面公开的示例,这意味着对于 year=2007 & area=24 & quarter=1 我将从 year=2006 & area=24 & quarter 1 借用信息,依此类推。
我正在尝试在 R 中构建一个函数,我可以在其中根据某些规范对原始数据帧进行子集化,然后将这个子集化的数据帧转换成一个比例 table。
不幸的是,对于某些特定的规范,我没有数据,其中一些子集会产生一个空数据框;因此无法计算出比例table。所以,我想做的是从我有一个非空子集数据帧的最近时间步长开始,并将它用作空子集数据帧的输入。
以下是对我的数据框和函数的一些见解:
我的原始数据框看起来 +/- 如下:
| 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 |
这里year, quarter and area指的是特定时间(Year & Quarter ) 和 X 编号的区域。对个人进行了测量 (no_individuals)。例如,从第一行我们得到,在 2005 年第一季度,在区域 24 中,我有 8 个个体,长度 class (lenCLs) 为 380 mm年龄=3。值得一提的是,对于特定的年份、季度和区域组合,我可以有不同的长度 classes 和年龄(因此,多行)!
所以我想做的基本上是对特定年份、季度和区域组合的原始数据框进行子集化,然后根据每个长度中的个体数量从该组合中计算一个比例 table class。
到目前为止,我的基本功能如下所示:
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”和“[=37=”列中的 NA ]age”相应。
另请注意,在某些情况下,我没有特定年份的数据!在上面的示例中,可以通过查看 2007 年的区域 24 来了解这一点。在这种情况下,我无法借用最近季度的信息,而需要借用前一年的信息。这意味着对于 year=2007 & area=24 & quarter=1 我将从 year=2006 & area=24 & quarter 1[=50] 借用信息=],依此类推。
我试图通过指定一些额外的规则将其包含在我的函数中,但由于我的编程技能不佳,我没有取得任何进展。
因此,我们将非常感谢任何帮助。
这是我要更新的 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")
}
}
我不知道您是否遇到过 MICE,但它是一个非常酷且全面的变量插补工具。它还允许您查看估算数据的分布情况,以便您可以选择最适合您的问题的方法。检查 this brief explanation and the original package description
所以,我终于找到了解决我问题的部分方法,并将我的函数包含在这里以防有人感兴趣:
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 中借用数据,其中包含同一地区所有季度的数据。 对于上面公开的示例,这意味着对于 year=2007 & area=24 & quarter=1 我将从 year=2006 & area=24 & quarter 1 借用信息,依此类推。