繁体   English   中英

从数据框中有条件地选择重复测量

[英]Conditional selection of repeated measures from data frame

我有数据,在可变数量的时间点对每个主题(id)进行重复测量。 我想为每个主题保留两行,时间点== 0和最接近4的时间点。在两个候选时间点距离4等距离的情况下,例如(3,5),我想选择最低的(3) )。

如下图中的“选择”列所示,不会保留带有“x”的行。

 dat <- structure(list(id = c(172507L, 172507L, 172507L, 172525L, 172525L, 
172525L, 172526L, 172526L, 172526L, 172527L, 172527L, 172527L, 
172527L, 172527L), timepoint = c(0L, 2L, 6L, 0L, 4L, 5L, 0L, 
5L, 2L, 2L, 3L, 5L, 6L, 0L)), class = "data.frame", row.names = c(NA, 
-14L))

在此输入图像描述

我们可以通过idtimepoint进行arrange ,并且对于每个组,当timepoint == 0时选择第一个出现,并且在4 - timepoint之间选择最小绝对值。 因为我们已经按timepoint安排了它which.min将选择具有较低值的第一个timepoint (如果是平局)。

library(dplyr)
dat %>%
  arrange(id, timepoint) %>%
  group_by(id) %>%
  slice(c(which.max(timepoint == 0), which.min(abs(4- timepoint))))

#     id timepoint
#   <int>     <int>
#1 172507         0
#2 172507         2
#3 172525         0
#4 172525         4
#5 172526         0
#6 172526         5
#7 172527         0
#8 172527         3

你能做这样的事吗? 按距离排列然后按时间点排列最小的最接近的值。 然后,您可以使用first()函数获取第一个值,或者在时间点为零时过滤。

library(tidyverse)

dat %>% 
  mutate(dist = abs(4-timepoint)) %>% 
  arrange(id, dist, timepoint) %>% 
  group_by(id) %>% 
  filter(timepoint %in% c(0, first(timepoint))) %>% 
  ungroup() %>% 
  arrange(id, timepoint)

这是data.table解决方案。 它依赖于每个ID的时间点为0的假设。否则,您应该使用which.max(timepoint == 0) 感谢Ronak Shah的which.min方法。

编辑:更改为match(TRUE, timepoint == 0)并修复了基本R方法中的问题。

library(data.table)

dt <- as.data.table(dat)

dt[order(timepoint),
 .SD[c(match(TRUE, timepoint == 0), which.min(abs(4- timepoint)))],
 by = id]

对于踢球,这里是基地R:

do.call(rbind, by(dat[order(dat$timepoint), ], dat[order(dat$timepoint), ], function(x) x[c(match(TRUE, x$timepoint == 0), which.min(abs(4-x$timepoint))),]) )

这样的事情应该有效:

zeros <- 
  dat %>% 
  filter(timepoint == 0) %>% 
  transmute(id, timepoint)

nonzeros <- 
  dat %>% 
  filter(timepoint != 0) %>% 
  mutate(diff = abs(timepoint - 4)) %>% 
  group_by(id) %>% 
  filter(diff == min(diff)) %>% 
  arrange(timepoint) %>% 
  slice(1) %>% 
  ungroup() %>% 
  transmute(id, timepoint)

df <-
  bind_rows(zeros, nonzeros) %>% 
  arrange(id, timepoint)

可能有一种方法可以在一个管道中执行此操作,但我可以更轻松地直观地查看这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM