R 循环浏览分组数据并执行

R 循环浏览分组数据并执行,r,loops,dplyr,R,Loops,Dplyr,假设我有以下示例: 我的原始数据集包括从VisitLink到dis3的变量。我想创建一个新的varnew,这样当我按患者对数据进行分组时,回顾该患者就诊前20天的情况,检查当时的任何就诊中是否存在Dis1。我想要的新是: 我做了几次尝试,但他们都忽略了分组 Patient DaysToEvent Dis1 Dis2 Dis3 new 1 130 TRUE FALSE FALSE TRUE 1 135 FALSE FALSE F

假设我有以下示例:

我的原始数据集包括从
VisitLink
dis3
的变量。我想创建一个新的var
new
,这样当我按
患者
对数据进行分组时,回顾该患者就诊前20天的情况,检查当时的任何就诊中是否存在
Dis1
。我想要的
是:

我做了几次尝试,但他们都忽略了分组

Patient DaysToEvent  Dis1  Dis2  Dis3   new
      1         130  TRUE FALSE FALSE  TRUE
      1         135 FALSE FALSE FALSE  TRUE
      2         456  TRUE  TRUE FALSE  TRUE
      2         500 FALSE FALSE FALSE  FALSE
      2         550  TRUE FALSE FALSE  TRUE
      2         560 FALSE  TRUE  TRUE  TRUE
      3         200 FALSE FALSE FALSE  FALSE
      3         400  TRUE  TRUE FALSE  TRUE
      3         410 FALSE  TRUE FALSE  TRUE
      3         510 FALSE FALSE FALSE  FALSE
      4           1  TRUE FALSE FALSE  TRUE
      4          20 FALSE  TRUE FALSE  TRUE
      4         110 FALSE FALSE FALSE  FALSE
谢谢大家!

1)创建一个函数
genu new
,为每位患者填写缺失的天数,给出
m
。然后,它使用
rollappyr
any(…,na.rm=TRUE)
来查找后面20个或更少的元素中是否有一个是真的,然后使用
window
将结果重新划分为存在的天数。要将其应用于所有患者,请使用
ave
ave
将强制gen_new
生成的逻辑为0/1,因此将其输出与1进行比较,以转换回逻辑

library(zoo)

n <- nrow(DF)

gen_new <- function(ix) with(DF[ix, ], {
  rng <- range(DaysToEvent)
  m <- merge(zoo(Dis1, DaysToEvent), zoo(, seq(rng[1], rng[2])))
  window(rollapplyr(m, 20, any, na.rm = TRUE, partial = TRUE), DaysToEvent)
})

DF <- transform(DF, new2 = ave(1:n, Patient, FUN = gen_new) == 1)

# check that new and new2 are the same
identical(DF$new, DF$new2)
## [1] TRUE
注:可复制形式的输入数据
DF

Lines <- "Patient DaysToEvent  Dis1  Dis2  Dis3   new
      1         130  TRUE FALSE FALSE  TRUE
      1         135 FALSE FALSE FALSE  TRUE
      2         456  TRUE  TRUE FALSE  TRUE
      2         500 FALSE FALSE FALSE  FALSE
      2         550  TRUE FALSE FALSE  TRUE
      2         560 FALSE  TRUE  TRUE  TRUE
      3         200 FALSE FALSE FALSE  FALSE
      3         400  TRUE  TRUE FALSE  TRUE
      3         410 FALSE  TRUE FALSE  TRUE
      3         510 FALSE FALSE FALSE  FALSE
      4           1  TRUE FALSE FALSE  TRUE
      4          20 FALSE  TRUE FALSE  TRUE
      4         110 FALSE FALSE FALSE  FALSE"
DF <- read.table(text = Lines, header = TRUE)

行我愿意接受更有效的建议,但这里是使用
dplyr的解决方案:

library(tidyr)
library(dplyr)

group_by(mydata,Patient) %>% 
    do(new = sapply(.$DaysToEvent,function(x)
        {
            any(.$Dis1*between(.$DaysToEvent,x-20,x))
        }
    ) %>% 
    unnest()

你能提供一个可复制的例子吗?你提供的列
new
包括你的预期输出?如果是这样,我很难理解您想要什么。@Jimbou
new
是我想要的输出。我只是编了个例子。事实上,我正在尝试对300万条记录执行此操作,因此我无法手动执行此操作it@raistlin你能解释一下你的问题吗?为了澄清这一点,我想让代码产生
新的
函数。让我进一步解释,对于患者#1,尽管他没有被诊断出患有第一种疾病,但在就诊前20天内,他在早期事件中被诊断为该疾病呈阳性,这就是为什么我们添加了第二种解决方案。感谢您的建议。我在你的评论中了解了动物园的功能,这很有趣。然而,有一个更简单的方法来做,我曾经提出过一次,但现在却陷入了取回它的困境。您的方法虽然有效,但需要很长的运行时间,我将在没有超级计算机的情况下对300万个观测值执行此过程。当我在回答中的注释中对DF运行此过程时,它失败并出现错误。@G.Grothendieck有趣。这是哪一个错误?并确保您三天内装入图书馆。如果你觉得这个姿势有帮助,请投赞成票。我正试图建立这样的“声誉”,开始一个新的R会话,复制并粘贴在我答案末尾的注释中的代码,输入行
mydata我按照您的指示进行操作,没有问题我正在使用dplyr_0.7.1和tidyr_0.6.3对R 3.4.0进行修补(Windows)。我得到的错误消息是:mutate_impl(.data,dots)中的错误:Column
new
必须是长度1(组大小),而不是2
library(tidyr)
library(dplyr)

group_by(mydata,Patient) %>% 
    do(new = sapply(.$DaysToEvent,function(x)
        {
            any(.$Dis1*between(.$DaysToEvent,x-20,x))
        }
    ) %>% 
    unnest()