寻找在R或Stata中查询子组观测值的有效方法

寻找在R或Stata中查询子组观测值的有效方法,r,stata,R,Stata,我想编写一个函数,根据唯一值[id]子组中的所有其他记录,对数据集中的每条记录执行操作。我对R非常陌生,但我知道您可以使用以下方法基于条件查询记录子集: df$date[id == "1234"] 是否可以将“1234”替换为从函数所操作的唯一行派生的变量?类似于 df$date[id == df$id] ,以便提取[id]与索引行的[id]匹配的[date]值?实际上,我希望在循环中使用它,其中对于x的值,我可以使用以下方法查询特定的[date]值: df$date[id == df$id

我想编写一个函数,根据唯一值[id]子组中的所有其他记录,对数据集中的每条记录执行操作。我对R非常陌生,但我知道您可以使用以下方法基于条件查询记录子集:

df$date[id == "1234"]
是否可以将“1234”替换为从函数所操作的唯一行派生的变量?类似于

df$date[id == df$id]
,以便提取[id]与索引行的[id]匹配的[date]值?实际上,我希望在循环中使用它,其中对于x的值,我可以使用以下方法查询特定的[date]值:

df$date[id == df$id & order == x]
对于每个唯一的[id],我的数据集都有多条记录。最后,我想将每个记录的[date_1]值与每个索引记录的[id]子组中所有其他记录的[date_2]值进行比较。数据如下所示:

[id] | [order] | [date_1] | [date_2] |
-------------------------------------- 
  A  |    1    |    1/1   |    1/30  |
  A  |    2    |    1/5   |    1/5   |
  A  |    3    |    1/7   |    1/8   |
  A  |    4    |    1/9   |    1/9   |
 -------------------------------------
  B  |    1    |    3/7   |    3/10  |
  B  |    2    |    4/1   |    4/9   |
--------------------------------------
for x = 1/max(order){ 
    df$episode_start <- 1 if df$date_1 - df$date_2[id == df$id & order == x] > 1
    }
[id] | [order] | [date_1] | [date_2] | [episode_start]
------------------------------------------------------ 
  A  |    1    |    1/1   |    1/30  |       1
  A  |    2    |    1/5   |    1/5   |       0
  A  |    3    |    1/7   |    1/8   |       0
  A  |    4    |    1/9   |    1/9   |       0
 -----------------------------------------------------
  B  |    1    |    3/7   |    3/10  |       1
  B  |    2    |    4/1   |    4/9   |       1
------------------------------------------------------
虽然这可以通过循环每个唯一值[id]然后循环每个唯一值[order]来实现,但记录的数量(500-1000万)证明了这种方法非常缓慢且资源密集。我想知道是否有一种更有效的方法可以简单地循环[order]值,然后同时计算每个记录的这个操作

正如我所说,我是R新手,所以我还不确定所有东西的确切语法,但我正在描绘这样的画面:

[id] | [order] | [date_1] | [date_2] |
-------------------------------------- 
  A  |    1    |    1/1   |    1/30  |
  A  |    2    |    1/5   |    1/5   |
  A  |    3    |    1/7   |    1/8   |
  A  |    4    |    1/9   |    1/9   |
 -------------------------------------
  B  |    1    |    3/7   |    3/10  |
  B  |    2    |    4/1   |    4/9   |
--------------------------------------
for x = 1/max(order){ 
    df$episode_start <- 1 if df$date_1 - df$date_2[id == df$id & order == x] > 1
    }
[id] | [order] | [date_1] | [date_2] | [episode_start]
------------------------------------------------------ 
  A  |    1    |    1/1   |    1/30  |       1
  A  |    2    |    1/5   |    1/5   |       0
  A  |    3    |    1/7   |    1/8   |       0
  A  |    4    |    1/9   |    1/9   |       0
 -----------------------------------------------------
  B  |    1    |    3/7   |    3/10  |       1
  B  |    2    |    4/1   |    4/9   |       1
------------------------------------------------------

提前谢谢。非常感谢任何帮助或指导。注意:我主要在Stata中工作,并尝试使用-bysort-command执行类似的操作,但没有效果。我想也许R更适合这个。欢迎使用任何一种方法提出建议。

我会使用
dplyr
软件包解决这个问题,这是一个fantatsic数据处理工具,您可以通过运行
install.packages('dplyr')
然后运行
library('dplyr')
来安装

此软件包的备忘单非常雄辩地解释了如何操作数据:


我不完全确定你要计算什么。是否尝试创建一个新列,并基于每行中的值进行计算?或者,您是否正在尝试为
ID
的每个唯一值计算一些内容?在前一种情况下,我将使用
dplyr::mutate(df,newcolumn=some_操作)
。在后一种情况下,我将使用
groupby(id)
,然后使用
filter()
summary()
等函数为每个id生成一个具有一行的新数据帧。

我将使用
dplyr
包解决这个问题,这是一个可以通过运行
install.packages('dplyr')安装的fantasic数据处理工具
然后是
库('dplyr')

此软件包的备忘单非常雄辩地解释了如何操作数据:


我不完全确定你要计算什么。是否尝试创建一个新列,并基于每行中的值进行计算?或者,您是否正在尝试为
ID
的每个唯一值计算一些内容?在前一种情况下,我将使用
dplyr::mutate(df,newcolumn=some_操作)
。在后一种情况下,我将使用
groupby(id)
,然后使用
filter()
summary()
等函数为每个id生成一个新的数据框,每个id有一行。

下面是一些让您开始使用
数据的东西。R中的table
包:

data <- read.table(text = "id order date_1 date_2 
A 1 2016-01-01 2016-01-30 
A 2 2016-01-05 2016-01-05
A 3 2016-01-07 2016-01-08
A 4 2016-01-09 2016-01-09
B 1 2016-03-07 2016-03-10
B 2 2016-04-01 2016-04-9", header = T)
library(data.table)
data$date_1 <- as.Date(data$date_1)
data$date_2 <- as.Date(data$date_2)
dt <- data.table(data, key = c("date_1", "date_2"))

res <- foverlaps(dt, dt, by.x = c("date_1", "date_2"), by.y = c("date_1", "date_2"))

# Remove matches from irrelevant groups.
res <- res[id == i.id]

# Find the period start date.
res[, min.date := min(i.date_1), by = .(id, order)]
res[, period.start := (date_1 == min.date)]

# Order records according to the period start date.
res <- res[order(id, order, i.date_1)]
# Remove duplicate rows
res <- res[, .SD[1], by = .(id, order)]

# Print resutls.
res[, .(id, order, date_1, date_2, period.start)][]

#       id order     date_1     date_2 period.start
# 1:  A     1 2016-01-01 2016-01-30         TRUE
# 2:  A     2 2016-01-05 2016-01-05        FALSE
# 3:  A     3 2016-01-07 2016-01-08        FALSE
# 4:  A     4 2016-01-09 2016-01-09        FALSE
# 5:  B     1 2016-03-07 2016-03-10         TRUE
# 6:  B     2 2016-04-01 2016-04-09         TRUE

data以下是一些让您开始使用
data的东西。R中的table
package:

data <- read.table(text = "id order date_1 date_2 
A 1 2016-01-01 2016-01-30 
A 2 2016-01-05 2016-01-05
A 3 2016-01-07 2016-01-08
A 4 2016-01-09 2016-01-09
B 1 2016-03-07 2016-03-10
B 2 2016-04-01 2016-04-9", header = T)
library(data.table)
data$date_1 <- as.Date(data$date_1)
data$date_2 <- as.Date(data$date_2)
dt <- data.table(data, key = c("date_1", "date_2"))

res <- foverlaps(dt, dt, by.x = c("date_1", "date_2"), by.y = c("date_1", "date_2"))

# Remove matches from irrelevant groups.
res <- res[id == i.id]

# Find the period start date.
res[, min.date := min(i.date_1), by = .(id, order)]
res[, period.start := (date_1 == min.date)]

# Order records according to the period start date.
res <- res[order(id, order, i.date_1)]
# Remove duplicate rows
res <- res[, .SD[1], by = .(id, order)]

# Print resutls.
res[, .(id, order, date_1, date_2, period.start)][]

#       id order     date_1     date_2 period.start
# 1:  A     1 2016-01-01 2016-01-30         TRUE
# 2:  A     2 2016-01-05 2016-01-05        FALSE
# 3:  A     3 2016-01-07 2016-01-08        FALSE
# 4:  A     4 2016-01-09 2016-01-09        FALSE
# 5:  B     1 2016-03-07 2016-03-10         TRUE
# 6:  B     2 2016-04-01 2016-04-09         TRUE

数据获取子集进行处理的一种方便方法是使用
by
。这将自动为data.frame(在本例中是按ID)子集,并允许您集中精力处理每个ID的记录

result <- by(df, df$id, function(x){
              ## identify start dates for sub-group
             })

获取子集进行处理的一种方便方法是使用
by
。这将自动为data.frame(在本例中是按ID)子集,并允许您集中精力处理每个ID的记录

result <- by(df, df$id, function(x){
              ## identify start dates for sub-group
             })

住院时间重叠的问题不时出现在Statalist上。请看一个例子。解决方案是将入院/出院日期二元表转换为长格式,并按时间顺序排列这两个事件。新的住院期可能是患者的第一次观察,也可能是患者在前一次观察结束时出院。下面是一个示例,数据来自Bulat的R解决方案(修改为添加2个附加支柱):

结果是:

. list id order date_1 date_2 spell newspell, sepby(id spell)

     +---------------------------------------------------------+
     | id   order       date_1       date_2   spell   newspell |
     |---------------------------------------------------------|
  1. |  A       1   2016-01-01   2016-01-30       1          1 |
  2. |  A       2   2016-01-05   2016-01-05       1          0 |
  3. |  A       3   2016-01-07   2016-01-08       1          0 |
  4. |  A       4   2016-01-09   2016-01-09       1          0 |
     |---------------------------------------------------------|
  5. |  A       5   2016-02-09   2016-02-09       2          1 |
     |---------------------------------------------------------|
  6. |  B       1   2016-03-07   2016-03-10       1          1 |
  7. |  B       2   2016-03-08   2016-03-08       1          0 |
     |---------------------------------------------------------|
  8. |  B       3   2016-04-01    2016-04-9       2          1 |
     +---------------------------------------------------------+

住院时间重叠的问题不时出现在Statalist上。请看一个例子。解决方案是将入院/出院日期二元表转换为长格式,并按时间顺序排列这两个事件。新的住院期可能是患者的第一次观察,也可能是患者在前一次观察结束时出院。下面是一个示例,数据来自Bulat的R解决方案(修改为添加2个附加支柱):

结果是:

. list id order date_1 date_2 spell newspell, sepby(id spell)

     +---------------------------------------------------------+
     | id   order       date_1       date_2   spell   newspell |
     |---------------------------------------------------------|
  1. |  A       1   2016-01-01   2016-01-30       1          1 |
  2. |  A       2   2016-01-05   2016-01-05       1          0 |
  3. |  A       3   2016-01-07   2016-01-08       1          0 |
  4. |  A       4   2016-01-09   2016-01-09       1          0 |
     |---------------------------------------------------------|
  5. |  A       5   2016-02-09   2016-02-09       2          1 |
     |---------------------------------------------------------|
  6. |  B       1   2016-03-07   2016-03-10       1          1 |
  7. |  B       2   2016-03-08   2016-03-08       1          0 |
     |---------------------------------------------------------|
  8. |  B       3   2016-04-01    2016-04-9       2          1 |
     +---------------------------------------------------------+

如果你也想问关于Stata的问题,那么乐观的假设是人们会通读一个长的以R为中心的问题,然后进行翻译。有人两种语言都很流利,但你在这方面成功的可能性很低。如果您同时寻求Stata建议,我建议您删除Stata标签,并提及和询问以Stata术语表述的单独Stata问题。当然,我不反对R问题,但我自己不能解决这个问题。如果你也想问关于斯塔塔的问题,可以乐观地假设人们会通读一个以R为中心的长问题,然后进行翻译。有人两种语言都很流利,但你在这方面成功的可能性很低。如果您同时寻求Stata建议,我建议您删除Stata标签,并提及和询问以Stata术语表述的单独Stata问题。当然,我不反对R问题,但我自己无法解决。太好了这似乎完全符合我的需要。我需要花一些时间来更熟悉foverlaps(),但谢谢您的指点