0

我有一个创建新行的自定义函数,它从第一行复制数据并在特定列中添加等于数字的行。现在,如果每个 id 只有一个数据条目,则该函数运行良好。我需要的是当数据对一个 id 有多行时,该函数才能工作。

我的数据包括 id,即个人 id;阶段,即人所处的阶段;开始/结束,即开始和结束日期;MonthDiff 是开始日期和结束日期之间的差异,以及等于 0 或 1 的 Censor。

我需要按阶段对函数进行分组,并将行向下复制等于该阶段的月份差异,然后重新启动。

到目前为止我所拥有的:

df<-data.frame(id=c('A','A','A'),
           Stage=c(1,2,3),
           Start=c(as.Date('2014-01-01'),as.Date('2016-01-01'),as.Date('2019-01-01')),
           End=c(as.Date('2015-12-31'),as.Date('2018-12-31'),as.Date('2020-02-01')),
           MonthDiff=c(23,35,13),
           Censor=c(0,0,1))

PLPP <- function(data, id,Stage, period, event) 
{stopifnot(is.matrix(data) || is.data.frame(data))
 stopifnot(c(id, period, event) %in% c(colnames(data), 1:ncol(data)))

 if (any(is.na(data[, c(id, period, event)]))) {
stop("PLPP cannot currently handle missing data in the id, period, or event variables")
}
       period = {
       index <- rep(1:nrow(data), data[, period])
       idmax<-cumsum(data[, period])
       reve <- !data[, event]
       dat <- data[index, ]
       dat[, period] <- ave(dat[, period], dat[, id], FUN = seq_along)
       dat[, event] <- 0
       dat[idmax, event] <- reve}


rownames(dat) <- NULL
 return(dat)
}

tpp<-PLPP(df,id='id',Stage = 'Stage',period = 'MonthDiff',event = 'Censor')

 test<-df%>%group_by(Stage)%>%do(tpp)

我对当前代码的问题是 group_by 语句没有在新阶段重新启动。

我尝试过的一些参考资料:如何在函数中使用 group_by在函数中使用 dplyr group_by

4

1 回答 1

1

这里有几个问题。首先,该变量是一个数据框,因此将其传递给就好像它是一个函数tpp并没有多大意义。do您需要确保tpp是一个将数据框作为参数的函数:

library(tidyverse)

tpp <- function(df)
{
  PLPP(df, id='id', Stage = 'Stage', period = 'MonthDiff', event = 'Censor')
}

PLPP函数本身中,您的period = {部分似乎不喜欢处理分组 tibble 中列的分配。如果您在本节之前显式转换为 data.frame,它将按预期工作:

PLPP <- function(data, id,Stage, period, event)
{
  stopifnot(is.matrix(data) || is.data.frame(data))
  stopifnot(c(id, period, event) %in% c(colnames(data), 1:ncol(data)))

  if (any(is.na(data[, c(id, period, event)])))
  {
     stop("PLPP cannot currently handle missing data in the id, ",
          "period, or event variables")
  }

  data <- as.data.frame(data)

  period = {
    index <- rep(1:nrow(data), data[, period])
    idmax <- cumsum(data[, period])
    reve  <- !data[, event]
    dat   <- data[index, ]
    dat[, period] <- ave(dat[, period], dat[, id], FUN = seq_along)
    dat[, event]  <- 0
    dat[idmax, event] <- reve
  }

 rownames(dat) <- NULL
 return(dat)
}

所以现在你可以这样做:

test <- df %>% group_by(Stage) %>% do(tpp(.))

你得到

test
#> # A tibble: 71 x 6
#> # Groups:   Stage [3]
#>    id    Stage Start      End        MonthDiff Censor
#>    <fct> <dbl> <date>     <date>         <dbl>  <dbl>
#>  1 A         1 2014-01-01 2015-12-31         1      0
#>  2 A         1 2014-01-01 2015-12-31         2      0
#>  3 A         1 2014-01-01 2015-12-31         3      0
#>  4 A         1 2014-01-01 2015-12-31         4      0
#>  5 A         1 2014-01-01 2015-12-31         5      0
#>  6 A         1 2014-01-01 2015-12-31         6      0
#>  7 A         1 2014-01-01 2015-12-31         7      0
#>  8 A         1 2014-01-01 2015-12-31         8      0
#>  9 A         1 2014-01-01 2015-12-31         9      0
#> 10 A         1 2014-01-01 2015-12-31        10      0
#> # ... with 61 more rows

每个阶段都有适当的编号:

test$MonthDiff
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  1  2  3  4  5
#> [29]  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#> [57] 34 35  1  2  3  4  5  6  7  8  9 10 11 12 13
于 2020-02-26T14:37:35.097 回答