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

时间:2019-05-02 23:05:52

标签: r dplyr data.table

我有在不同时间点对每个主题(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))

enter image description here

4 个答案:

答案 0 :(得分:6)

我们可以用arrangeidtimepoint,并为每个组选择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

答案 1 :(得分:2)

您能做这样的事情吗?按距离排列,然后时间点将首先放置最小的最近值。然后,您可以使用/container2函数获取时间点为零时的第一个值或过滤器。

<div>
  <header>container1</header>
</div>
<div>
  <header>container2</header> 
  <Page1 />
</div>

答案 2 :(得分:2)

这是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))),]) )

答案 3 :(得分:0)

类似的事情应该起作用:

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)

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