我有一个巨大的数据框,其中包含对几百个人的几个变量的许多时间相关观察。每个人在ID列中都有一个唯一的编号。我将使用下面模拟的数据,其结构类似于我的数据来问我的问题:
set.seed(123)
dat <- data.frame(ID = rep(letters[1:10], each = 10),
time = rep(c(1:10), times = 10),
var1 = rnorm(100))
Run Code Online (Sandbox Code Playgroud)
请注意,在真实数据中,每个 的实际观察次数是不同的ID。假设有几个人(例如,IDs:b、e 和 g)我需要对其进行观察并完全“翻转”或“反转”其顺序,并且仍然保留每个time. 我的意思是(以个人 b 为例)个人 b 在数据框中的第一个观察结果将是“时间间隔”10 而不是“时间间隔”1 的数据。换句话说,数据看起来像这样:
ID time Var1
a 1
a 2
… …
a 10
b 10
b 9
b 8
… …
b 1
c 1
c 2
c 3
c 4
ect...
Run Code Online (Sandbox Code Playgroud)
什么是做到这一点,保持在数据帧中的位置(即,最安全的方式b在间的住宿a和c等..)?
一种选择是group_split通过 ID 并根据值“b”、“e”、“g”是否是“ID”来arrange循环执行listmapany%n%
library(dplyr)
library(purrr)
out <- dat %>%
group_split(ID) %>%
map_dfr(~ if(any(c('b', 'e', 'g') %in% first(.x$ID)))
.x %>%
arrange(desc(time)) else .x)
out %>%
filter(ID %in% c('a', 'b'))
# A tibble: 20 x 3
# ID time var1
# <fct> <int> <dbl>
# 1 a 1 -0.560
# 2 a 2 -0.230
# 3 a 3 1.56
# 4 a 4 0.0705
# 5 a 5 0.129
# 6 a 6 1.72
# 7 a 7 0.461
# 8 a 8 -1.27
# 9 a 9 -0.687
#10 a 10 -0.446
#11 b 10 -0.473
#12 b 9 0.701
#13 b 8 -1.97
#14 b 7 0.498
#15 b 6 1.79
#16 b 5 -0.556
#17 b 4 0.111
#18 b 3 0.401
#19 b 2 0.360
#20 b 1 1.22
Run Code Online (Sandbox Code Playgroud)
或者我们可以以一种 hacky 的方式利用arrange,即根据 ID 'b'、'e'、'g' 将 更改time为负数,而其余为正数
out1 <- dat %>%
arrange(ID, time * c(1, -1)[c(1 + (ID %in% c('b', 'e', 'g')))])
Run Code Online (Sandbox Code Playgroud)
-检查
all.equal(out, out1, check.attributes = FALSE)
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |