首页 文章

组内插值

提问于
浏览
6

目标

我想在数据帧中的组内插值 . 这将为数据帧中的每个组提供任意数量的中间点 .

最小的工作示例

我有一个数据框,如:

OldDataFrame <- data.frame(ID   = c(1,1,1,2,2,2),
                           time = c(1,2,3,1,2,3),
                           Var1 = c(-0.6 , 0.2, -0.8 , 1.6 , 0.3 , -0.8),
                           Var2 = c(0.5 , 0.7, 0.6 , -0.3 , 1.5 , 0.4) )

我想得到一个像这样的函数:

TimeInterpolateByGroup <- function(DataFrame, 
                                   GroupingVariable, 
                                   TimeVariable,
                                   TimeInterval){
  #Something Here
}

如果我不必指定列来执行此操作并且它可以在_859600_中的 numcolwise 之类的每个数字列上自动运行,这将非常方便

所以我可以像这样应用它:

NewDataFrame = TimeInterpolateByGroup(DataFrame         = OldDataFrame,
                                      GroupingVariable  = "ID",
                                      TimeVariable      = "time",
                                      TimeInterval      = 0.25)

获取NewDataFrame为:

NewDataFrame = data.frame(ID    =   c(  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2   ),
                          time  =   c(  1,  1.25,   1.5,    1.75,   2,  2.25,   2.5,    2.75,   3,  1,  1.25,   1.5,    1.75,   2,  2.25,   2.5,    2.75,   3   ), 
                           Var1 =   c(  -0.6,   -0.4,   -0.2,   0,  0.2,    -0.05,  -0.3,   -0.55,  -0.8,   1.6,    1.275,  0.95,   0.625,  0.3,    0.025,  -0.25,  -0.525, -0.8    ), 
                           Var2 =   c(  0.5,    0.55,   0.6,    0.65,   0.7,    0.675,  0.65,   0.625,  0.6,    -0.3,   0.15,   0.6,    1.05,   1.5,    1.225,  0.95,   0.675,  0.4 ))

或图片形式我想:

enter image description here

相关问题不太奏效

Interpolate variables on subsets of dataframe

  • 使用 plyr 类型的方法似乎是在正确的方向,但有一个令人困惑的例子,没有能够拥有任意数量的中间插值点 . 这对于动画应用程序很重要(见下文),我不知道在获得平滑动画时需要多少个中间时间点 .

其他一些答案使用时间序列方法,但不允许按组进行分段 .

我还考虑使用纵向数据包,但对于应该是一个简单的问题,这似乎不必要地复杂化 .

所需应用程序

我想要一个包含Var1和Var2的x-y图,其中每个ID点的时间点为1.然后我想使用 animate 包来查看随着时间的推移而移动的点 . 为了顺利地做到这一点,我需要中间点的所有坐标集 .

2 回答

  • 3

    我很确定下面的代码给出了正确的答案,除了由于使用approx()函数导致的微小数值不精确 . 基本思想是使用ddply来分割和组合数据帧,并使用近似进行插值 .

    library(plyr)
    
    # time_interpolate is a helper function for TimeInterpolateByGroup
    # that operates on each of the groups. In the input to this function,
    # the GroupingVariable column of the data frame should be single-valued.
    # The function returns a (probably longer) data frame, with estimated
    # values for the times specified in the output_times array.
    time_interpolate <- function(data_frame,
                                 GroupingVariable,
                                 time_var,
                                 output_times) {
      input_times <- data_frame[, time_var]
      exclude_vars <- c(time_var, GroupingVariable)
      value_vars <- setdiff(colnames(data_frame), exclude_vars)
      output_df <- data.frame(rep(data_frame[1,GroupingVariable], length(output_times)), output_times)
      colnames(output_df) <- c(GroupingVariable, time_var)
      for (value_var in value_vars) {
        output_df[,value_var] <- approx(input_times, data_frame[, value_var], output_times)$y
      }
      return(output_df)
    }
    
    # A test for time_interpolate
    time_interpolate(OldDataFrame[1:3,], "ID" , "time", seq(from=1, to=3, by=0.25))
    
    TimeInterpolateByGroup <- function(DataFrame, 
                                       GroupingVariable, 
                                       TimeVariable,
                                       TimeInterval){
      min_time <- min(DataFrame[, TimeVariable])
      max_time <- max(DataFrame[, TimeVariable])
      output_times <- seq(from=min_time, to=max_time, by=TimeInterval)
      ddply(DataFrame,
            GroupingVariable,
            time_interpolate,
            GroupingVariable=GroupingVariable,
            time_var=TimeVariable,
            output_times=output_times)
    }
    
  • 3

    您也可以使用 zoo 来自 zoo 包 .

    library(zoo)
    my_fun <- function(DataFrame, GroupingVariable, TimeVariable, TimeInterval){
      do.call(rbind, by(DataFrame, DataFrame[ , GroupingVariable], function(dat){
        tt <- data.frame(time = seq(from = min(dat[ , TimeVariable]),
                                    to = max(dat[ , TimeVariable]),
                                    by = TimeInterval))
        dat2 <- merge(tt, dat, all.x = TRUE)
        na.approx(dat2)
      }))
    }
    
    my_fun(df, "ID", "time", 0.25)
    

相关问题