如何将性别纳入算法,编写循环函数计算数据框的Time字段
基于性别分组的插值计算方案
原始数据集
Age<-c(2,2.1,2.2,3.4,3.5,4.2,4.7,4.8,5,5.6,NA, 5.9, NA) R<-c(2,2.1,2.2,3.4,3.5,4.2,4.7,4.8,5,5.6,NA, 5.9, NA) sex<-c(1,0,1,1,1,1,1,0,0,0,NA, 0,1) df1<-data.frame(Age,R,sex) # 女性插值数据集 Age2<-seq(2,20,0.25) Mspline<-rnorm(73) df2.F<-data.frame(Age2, Mspline) # 男性插值数据集 Age2<-seq(2,20,0.25) Mspline<-rnorm(73) df2.M<-data.frame(Age2, Mspline)
需求说明
遍历df1的每条记录:
- 当
sex=1(女性)时,用df2.F的Age2和Mspline构建插值函数,计算对应Age的Time值 - 当
sex=0(男性)时,用df2.M的Age2和Mspline构建插值函数,计算对应Age的Time值 - 若
sex或Age为NA,Time保持NA
解决方案
方法1:向量化实现(推荐,R中更高效)
先提前构建好男女各自的插值函数,再通过逻辑索引批量赋值,避免循环:
# 构建女性插值函数 fM.F <- approxfun(df2.F$Age2, df2.F$Mspline, yleft = df2.F$Mspline[1], yright = df2.F$Mspline[nrow(df2.F)]) # 构建男性插值函数 fM.M <- approxfun(df2.M$Age2, df2.M$Mspline, yleft = df2.M$Mspline[1], yright = df2.M$Mspline[nrow(df2.M)]) # 初始化Time列 df1$Time <- NA # 按性别分组赋值 df1$Time[df1$sex == 1 & !is.na(df1$Age)] <- fM.F(df1$Age[df1$sex == 1 & !is.na(df1$Age)]) df1$Time[df1$sex == 0 & !is.na(df1$Age)] <- fM.M(df1$Age[df1$sex == 0 & !is.na(df1$Age)])
方法2:循环实现(满足遍历每条记录的需求)
如果一定要用循环遍历每行记录,可以这样写:
# 提前构建插值函数,避免循环内重复构建(提升效率) fM.F <- approxfun(df2.F$Age2, df2.F$Mspline, yleft = df2.F$Mspline[1], yright = df2.F$Mspline[nrow(df2.F)]) fM.M <- approxfun(df2.M$Age2, df2.M$Mspline, yleft = df2.M$Mspline[1], yright = df2.M$Mspline[nrow(df2.M)]) # 初始化Time列 df1$Time <- NA # 遍历每条记录 for(i in 1:nrow(df1)){ # 跳过sex或Age为NA的行 if(is.na(df1$sex[i]) || is.na(df1$Age[i])) next if(df1$sex[i] == 1){ df1$Time[i] <- fM.F(df1$Age[i]) } else if(df1$sex[i] == 0){ df1$Time[i] <- fM.M(df1$Age[i]) } }
说明
- 两种方法都提前构建插值函数,避免重复计算,提升效率
- 向量化方法在处理大数据集时性能远优于循环
- 自动处理NA值,当
sex或Age为NA时,Time保持NA
内容的提问来源于stack exchange,提问作者stats
相关产品推荐
相关产品推荐

