在数据框中选择观察值并反转它们的顺序

Rya*_*yan 6 r dataframe

我有一个巨大的数据框,其中包含对几百个人的几个变量的许多时间相关观察。每个人在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在间的住宿ac等..)?

akr*_*run 2

一种选择是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)