我的数据框看起来或多或少如下(原始数据框有12年的数据):
Year Quarter Age_1 Age_2 Age_3 Age_4
2005 1 158 120 665 32
2005 2 257 145 121 14
2005 3 68 69 336 65
2005 4 112 458 370 101
2006 1 75 457 741 26
2006 2 365 134 223 45
2006 3 257 121 654 341
2006 4 175 124 454 12
2007 1 697 554 217 47
2007 2 954 987 118 54
2007 4 498 235 112 65
年龄栏中的数字表示特定年份内特定季度的每个年龄组的个人数量。值得注意的是,有时并非特定年份的所有季度都有数据(例如,第三季度没有代表2007年)。此外,每行代表一个采样事件。虽然在此示例中未显示,但在原始数据集中,对于特定年份内的特定季度,我总是有多个采样事件。例如,对于2005年的第一季度,我有47个抽样事件,因此导致47行。
我现在想要的是一个数据框,结构如下:
Year Quarter Age_1 Age_2 Age_3 Age_4 Cohort
2005 1 158 120 665 32 158
2005 2 257 145 121 14 257
2005 3 68 69 336 65 68
2005 4 112 458 370 101 112
2006 1 75 457 741 26 457
2006 2 365 134 223 45 134
2006 3 257 121 654 341 121
2006 4 175 124 454 12 124
2007 1 697 554 217 47 47
2007 2 954 987 118 54 54
2007 4 498 235 112 65 65
在这种情况下,我想在我的原始数据集中创建一个新列(同类群组),它基本上沿着我的数据集跟踪我的同类群组。换句话说,当我在我的第一年数据(2005年的所有季度)中,我获取Age_1的行值并将其粘贴到新列中。当我移动到下一年(2006年)时,我将所有与Age_2相关的行值并将其粘贴到新列,依此类推。
我曾尝试使用以下功能,但不知何故它只适用于前几年:
extract_cohort_quarter <- function(d, yearclass=2005, quarterclass=1) {
ny <- 1:nlevels(d$Year) #no. of Year levels in the dataset
nq <- 1:nlevels(d$Quarter)
age0 <- (paste("age", ny, sep="_"))
year0 <- as.character(yearclass + ny - 1)
quarter <- as.character(rep(1:4, length(age0)))
age <- rep(age0,each=4)
year <- rep(year0,each=4)
df <- data.frame(year,age,quarter,stringsAsFactors=FALSE)
n <- nrow(df)
dnew <- NULL
for(i in 1:n) {
tmp <- subset(d, Year==df$year[i] & Quarter==df$quarter[i])
tmp$Cohort <- tmp[[age[i]]]
dnew <- rbind(dnew, tmp)
}
levels(dnew$Year) <- paste("Yearclass_", yearclass, ":",
year,":",quarter,":", age, sep="")
dnew
}
我的所有年份和季度都有大量从age_1到age_12的数据,因此我认为这与数据结构本身无关。
有没有更简单的解决方案来解决这个问题?或者有没有办法改进我的extract_cohort_quarter()函数?任何帮助将不胜感激。
-M
答案 0 :(得分:2)
我有一个简单的解决方案,但需要对data.table库有点了解。我认为您可以轻松地根据您的进一步需求进行调整。 这是数据:
DT <- as.data.table(list(Year = c(2005, 2005, 2005, 2005, 2006, 2006 ,2006 ,2006, 2007, 2007, 2007),
Quarter= c(1, 2, 3, 4 ,1 ,2 ,3 ,4 ,1 ,2 ,4),
Age_1 = c(158, 257, 68, 112 ,75, 365, 257, 175, 697 ,954, 498),
Age_2= c(120 ,145 ,69 ,458 ,457, 134 ,121 ,124 ,554 ,987, 235),
Age_3= c(665 ,121 ,336 ,370 ,741 ,223 ,654 ,454,217,118,112),
Age_4= c(32,14,65,101,26,45,341,12,47,54,65)
))
这是代码:
DT[,index := .GRP, by = Year]
DT[,cohort := get(paste0("Age_",index)),by = Year]
和输出:
> DT
Year Quarter Age_1 Age_2 Age_3 Age_4 index cohort
1: 2005 1 158 120 665 32 1 158
2: 2005 2 257 145 121 14 1 257
3: 2005 3 68 69 336 65 1 68
4: 2005 4 112 458 370 101 1 112
5: 2006 1 75 457 741 26 2 457
6: 2006 2 365 134 223 45 2 134
7: 2006 3 257 121 654 341 2 121
8: 2006 4 175 124 454 12 2 124
9: 2007 1 697 554 217 47 3 217
10: 2007 2 954 987 118 54 3 118
11: 2007 4 498 235 112 65 3 112
它的作用:
DT[,index := .GRP, by = Year]
为表中的所有不同年份创建索引(by = Year为年度组创建操作,.GRP在分组序列后创建索引)。 我使用它来调用名为Age_的列,并使用创建的数字
DT[,cohort := get(paste0("Age_",index)),by = Year]
您甚至可以在一行中完成所有工作
DT[,cohort := get(paste0("Age_",.GRP)),by = Year]
我希望它有所帮助
答案 1 :(得分:1)
以下是使用let regex = /(?!([A-Z]+))(\d+)(?=[A-Z]+)/g;
let values = 'A32CZ, GH2X, ABC19E'
let result = values.match(regex);
console.log(result);
tidyverse