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
的变量。我想创建一个新的varnew
,这样当我按患者
对数据进行分组时,回顾该患者就诊前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
包括你的预期输出?如果是这样,我很难理解您想要什么。@Jimbounew
是我想要的输出。我只是编了个例子。事实上,我正在尝试对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)中的错误:Columnnew
必须是长度1(组大小),而不是2
library(tidyr)
library(dplyr)
group_by(mydata,Patient) %>%
do(new = sapply(.$DaysToEvent,function(x)
{
any(.$Dis1*between(.$DaysToEvent,x-20,x))
}
) %>%
unnest()