【问题标题】:R - group_by utilizing splinefunR - group_by 利用 splinefun
【发布时间】:2014-07-08 19:23:05
【问题描述】:

我正在尝试按 Year 和 CountyID 对数据进行分组,然后对子集数据使用 splinefun(三次样条插值)。我对想法持开放态度,但 splinefun 是必须的,不能更改。

这是我尝试使用的代码:

age <- seq(from = 0, by = 5, length.out = 18)

TOT_POP <- df %.%
group_by(unique(df$Year), unique(df$CountyID) %.%
splinefun(age, c(0, cumsum(df$TOT_POP)), method = "hyman")

这是我的数据示例 Year = 2010 : 2013, Agegrp = 1 : 17 并且 CountyIDs 等于美国的所有县。

CountyID    Year        Agegrp      TOT_POP
1001        2010        1           3586
1001        2010        2           3952
1001        2010        3           4282
1001        2010        4           4136
1001        2010        5           3154

我正在做的是采用 Agegrp 1 : 17 并将分组拆分为 0 - 84 年。现在每个组代表 5 年。 splinefun 允许我这样做,同时为该过程提供一定程度的数学严谨性,即 splinefun 允许我提供美国每个县的每个年龄的人口总数。

最后,splinefun 代码本身可以工作,但在 group_by 函数中却不行,它会产生:

Error: wrong result size(4), expected 68 or 1. 

我使用的 splinefun 代码是这样工作的

TOT_POP <- splinefun(age, c(0, cumsum(df$TOT_POP)), 
           method  = "hyman") 

TOT_POP = pmax(0, diff(TOT_POP(c(0:85))))

在一年内对一个 CountyID 进行了测试。我需要在“x”年和大约 3200 个县迭代这个过程。

【问题讨论】:

  • 让我直说。您希望根据两个变量拆分数据框。然后,对于每个较小的数据帧,您想使用splinefun 得到样条函数映射ageTOT_POP?然后,您想使用该函数插入 0 到 85 岁之间所有年龄的总人口,因为您的原始数据只有 5、10、15、20 岁的人口......?也许您可以使用splitlapplyplyr 来实现这一点,并让某些东西发挥作用,然后有人会更好地为您提供dplyr 的帮助。
  • splinefun 将用于一个县和一年一次的 Aegrp 1 : 17 的数据子集。最终年龄组将是个人年龄 0 : 84。
  • 我还是一头雾水。也许您可以更改df 数据框?将Agegrp 替换为关联的age。例如,df$Agegrp = df$Agegrp*5colnames(df)[3] = "age"。这可能会简化您的问题。

标签: r group-by spline dplyr cubic-spline


【解决方案1】:
# Reproducible data set
set.seed(22)
df = data.frame( CountyID = rep(1001:1005,each = 100), 
                 Year = rep(2001:2010, each = 10),
                 Agegrp = sample(1:17, 500, replace=TRUE),
                 TOT_POP = rnorm(500, 10000, 2000))

# Convert Agegrp to age
df$Agegrp = df$Agegrp*5
colnames(df)[3] = "age"

# Make a spline function for every CountyID-Year combination
split.dfs = split(df, interaction(df$CountyID, df$Year))
spline.funs = lapply(split.dfs, function(x) splinefun(x[,"age"], x[,"TOT_POP"]))

# Use the spline functions to interpolate populations for all years between 0 and 85
new.split.dfs = list()
for( i in 1:length(split.dfs)) {
  new.split.dfs[[i]] = data.frame( CountyID=split.dfs[[i]]$CountyID[1],
                                   Year=split.dfs[[i]]$Year[1],
                                   age=0:85,
                                   TOT_POP=spline.funs[[i]](0:85))
}


# Does this do what you want? If so, then it will be 
# easier for others to work from here
# > head(new.split.dfs[[1]])
# CountyID Year age  TOT_POP
# 1     1001 2001   0 909033.4
# 2     1001 2001   1 833999.8
# 3     1001 2001   2 763181.8
# 4     1001 2001   3 696460.2
# 5     1001 2001   4 633716.0
# 6     1001 2001   5 574829.9
# > tail(new.split.dfs[[2]])
# CountyID Year age   TOT_POP
# 81     1002 2001  80 10201.693
# 82     1002 2001  81  9529.030
# 83     1002 2001  82  8768.306
# 84     1002 2001  83  7916.070
# 85     1002 2001  84  6968.874
# 86     1002 2001  85  5923.268

【讨论】:

    【解决方案2】:

    首先,我认为我在试图实现的目标中使用了错误的措辞,我深表歉意; group_by 实际上并不能解决问题。但是,我能够使用两个函数和 ddply 解决问题。这是解决问题的代码:

    interpolate <- function(x, ageVector){
    result <- splinefun(ageVector, 
              c(0, cumsum(x)), method = "hyman")
    diff(result(c(0:85)))
    }
    
    mainFunc <- function(df){
    
    age <- seq(from = 0, by = 5, length.out = 18)
    colNames <- setdiff(colnames(df)
                c("Year","CountyID","AgeGrp"))
    colWiseSpline <- colwise(interpolate, .cols = true,
                     age)(df[ , colNames])
    
    cbind(data.frame(
    Year = df$Year[1],
    County = df$CountyID[1],
    Agegrp = 0:84
    ),
    colWiseSpline
    )
    }
    
    CompleteMainRaw <- ddply(.data = df, 
                        .variables = .(CountyID, Year), 
                        .fun = mainFunc)
    

    代码现在按年份获取每个县,并在该人口数据子集上运行 splinefun。同时,它创建了一个带有结果的数据框,即将数据从 17 个年龄组拆分为 85 个年龄组,同时适当地考虑它;这就是 splinefun 所做的。

    谢谢!

    【讨论】:

      猜你喜欢
      • 2020-08-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      • 2021-08-28
      相关资源
      最近更新 更多