根据长格式数据集中的其他列键从一列中获取值

Fetching values from one column based on other column keys in long-formatted dataset

我有一个包含 100,000 多个人的长格式数据集,记录了 5 个不同时间点(不是按时间顺序)的门诊就诊情况。我在下面包含了一个示例数据集,它复制了我的数据格式:

我想创建一个新列 (clinic_number_extracted) 以获取与每个排序年龄(age_sorted 值)对应的诊所标识符 (clinic_number)对于每个参与者。 我在想可以使用 age_sorted_indexvisit_number 变量来做到这一点(生成键值对?),但我不太确定如何在 data.table 之外执行此操作。首选 tidyverse 解决方案。

我在 R 社区和堆栈交换中寻找线索,但未能准确找到我要找的东西(可能没有使用正确的搜索词)。我尝试使用 group_by(across())with_order(order_by()) 函数,但没有成功。我可能会创建一个具有一些 case_when() 条件的新变量,但如果重复 age_assessment_sorted values.

可能会 运行 成为问题
set.seed(42)

# Beginning dataset
das <- data.frame(id = rep(letters[1:3], each = 5), 
                  visit_number = rep(1:5, times = 3),
                  age_visit = c(50, rep(NA_real_, times = 7), 34, 40, 72, rep(NA_real_, times = 3), 87), 
                  clinic_number = sample(30:50, 15, replace=TRUE), 
                  age_sorted = c(50, rep(NA_real_, times = 4), 34, 40,rep(NA_real_, times = 3), 72, 87, rep(NA_real_, times = 3)), 
                  age_sorted_index = c(rep(1:5), 4, 5, rep(1:3), 1, 5, 2, 3, 4)) 

# Print out dataset
das
#>    id visit_number age_visit clinic_number age_sorted age_sorted_index
#> 1   a            1        50            46         50                1
#> 2   a            2        NA            34         NA                2
#> 3   a            3        NA            30         NA                3
#> 4   a            4        NA            39         NA                4
#> 5   a            5        NA            33         NA                5
#> 6   b            1        NA            47         34                4
#> 7   b            2        NA            46         40                5
#> 8   b            3        NA            44         NA                1
#> 9   b            4        34            36         NA                2
#> 10  b            5        40            33         NA                3
#> 11  c            1        72            34         72                1
#> 12  c            2        NA            43         87                5
#> 13  c            3        NA            49         NA                2
#> 14  c            4        NA            47         NA                3
#> 15  c            5        87            44         NA                4

所需数据:

das_final <- cbind(das, 
                  clinic_number_extracted = c(46, rep(NA_real_, times = 4), 36, 33, rep(NA_real_, times = 3), 34, 44, rep(NA_real_, times = 3)))

# Print out final dataset
das_final 
#>    id visit_number age_visit clinic_number age_sorted age_sorted_index
#> 1   a            1        50            46         50                1
#> 2   a            2        NA            34         NA                2
#> 3   a            3        NA            30         NA                3
#> 4   a            4        NA            39         NA                4
#> 5   a            5        NA            33         NA                5
#> 6   b            1        NA            47         34                4
#> 7   b            2        NA            46         40                5
#> 8   b            3        NA            44         NA                1
#> 9   b            4        34            36         NA                2
#> 10  b            5        40            33         NA                3
#> 11  c            1        72            34         72                1
#> 12  c            2        NA            43         87                5
#> 13  c            3        NA            49         NA                2
#> 14  c            4        NA            47         NA                3
#> 15  c            5        87            44         NA                4
#>    clinic_number_extracted
#> 1                       46
#> 2                       NA
#> 3                       NA
#> 4                       NA
#> 5                       NA
#> 6                       36
#> 7                       33
#> 8                       NA
#> 9                       NA
#> 10                      NA
#> 11                      34
#> 12                      44
#> 13                      NA
#> 14                      NA
#> 15                      NA

reprex package (v2.0.1)

创建于 2022-05-06

我们可以在 'age_sorted' 和 'age_visit' 之间使用 match,使用该索引对 'clinic_number' 进行子集化,并替换 [=18] 中为 NA 的元素=]到NA

library(dplyr)
das_final %>% 
  group_by(id) %>%
  mutate(clinic_new = clinic_number[match(age_sorted, age_visit)] * 
      NA^is.na(age_sorted)) %>%
  ungroup

-输出

# A tibble: 15 × 8
   id    visit_number age_visit clinic_number age_sorted age_sorted_index clinic_number_extracted clinic_new
   <chr>        <int>     <dbl>         <int>      <dbl>            <dbl>                   <dbl>      <dbl>
 1 a                1        50            46         50                1                      46         46
 2 a                2        NA            34         NA                2                      NA         NA
 3 a                3        NA            30         NA                3                      NA         NA
 4 a                4        NA            39         NA                4                      NA         NA
 5 a                5        NA            33         NA                5                      NA         NA
 6 b                1        NA            47         34                4                      36         36
 7 b                2        NA            46         40                5                      33         33
 8 b                3        NA            44         NA                1                      NA         NA
 9 b                4        34            36         NA                2                      NA         NA
10 b                5        40            33         NA                3                      NA         NA
11 c                1        72            34         72                1                      34         34
12 c                2        NA            43         87                5                      44         44
13 c                3        NA            49         NA                2                      NA         NA
14 c                4        NA            47         NA                3                      NA         NA
15 c                5        87            44         NA                4                      NA         NA

你能不能不用分组就这样做?它似乎解决了样本数据中的问题,但也许我遗漏了一些东西:

das$clinic_number_extracted <- ifelse(!is.na(das$age_sorted), das$clinic_number, NA)

输出:

#   id visit_number age_visit clinic_number age_sorted age_sorted_index clinic_number_extracted
1   a            1        50            46         50                1                      46
#2   a            2        NA            34         NA                2                      NA
#3   a            3        NA            30         NA                3                      NA
#4   a            4        NA            39         NA                4                      NA
#5   a            5        NA            33         NA                5                      NA
#6   b            1        NA            47         34                4                      47
#7   b            2        NA            46         40                5                      46
#8   b            3        NA            44         NA                1                      NA
#9   b            4        34            36         NA                2                      NA
#10  b            5        40            33         NA                3                      NA
#11  c            1        72            34         72                1                      34
#12  c            2        NA            43         87                5                      43
#13  c            3        NA            49         NA                2                      NA
#14  c            4        NA            47         NA                3                      NA
#15  c            5        87            44         NA                4                      NA

根据提供的所需数据进行测试:

all.equal(das[,"clinic_number_extracted"], das_final[,"clinic_number_extracted"])

#[1] TRUE