【问题标题】:Generating new variables for changes over time in longitudinal data with dplyr使用 dplyr 为纵向数据随时间的变化生成新变量
【发布时间】:2021-08-14 09:07:29
【问题描述】:

我有以下数据框:

t <- c(1, 2, 3, 1, 2, 3, 1, 2, 3)
i <- c(1, 1, 1, 2, 2, 2, 3, 3, 3)
x <- c(3, 3, 2, 0, NA, NA, 1, 3, NA)
y <- c(0, 0, 0, 0, 1, 1, 0, 0, 1)

df <- data.frame(t, i, x, y)
df

> df
  t i  x y
1 1 1  3 0
2 2 1  3 0
3 3 1  2 0
4 1 2  0 0
5 2 2 NA 1
6 3 2 NA 1
7 1 3  1 0
8 2 3  3 0
9 3 3 NA 1

这是一些示例纵向数据,其中包含 3 个时间点 (t)、3 个对象 (i) 以及 3 个对象 i 的两个变量 x 和 y。请注意,当 y 等于 1 时,x 始终为 NA。我想生成一个与 x 重复的新变量 z;但有一个区别:x 中的 NA 应该成为 x 中的最后一个可用值。这意味着,i = 2 中的 NA 都变为 0,而 i = 3 中的 NA 变为 3。结果如下数据帧:

  t i  x y z
1 1 1  3 0 3
2 2 1  3 0 3
3 3 1  2 0 2
4 1 2  0 0 0
5 2 2 NA 1 0
6 3 2 NA 1 0
7 1 3  1 0 1
8 2 3  3 0 3
9 3 3 NA 1 3

在最后一步中,当对象 i 的 y 始终为 0 时,我想将新变量 z 更改为 NA:

  t i  x y  z
1 1 1  3 0 NA
2 2 1  3 0 NA
3 3 1  2 0 NA
4 1 2  0 0  0
5 2 2 NA 1  0
6 3 2 NA 1  0
7 1 3  1 0  1
8 2 3  3 0  3
9 3 3 NA 1  3

所以最后,新变量 z 只包含关于 x 的信息,用于在 i 的水平上 y 的变化。但是,对我来说重要的是,最后一步(在 z 中生成 NA)是单独实现的。我感谢任何有关如何在 dplyr 中执行此操作的建议。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以使用zoo中的na.locf0

    library(dplyr)
    library(zoo)
    df %>%
          group_by(i) %>%
          mutate(z = na.locf0(x) * NA^(all(y == 0))) %>%
          ungroup
    # A tibble: 9 x 5
          t     i     x     y     z
      <dbl> <dbl> <dbl> <dbl> <dbl>
    1     1     1     3     0    NA
    2     2     1     3     0    NA
    3     3     1     2     0    NA
    4     1     2     0     0     0
    5     2     2    NA     1     0
    6     3     2    NA     1     0
    7     1     3     1     0     1
    8     2     3     3     0     3
    9     3     3    NA     1     3
    

    【讨论】:

      【解决方案2】:

      如果i 中的所有y 值均为0,您可以使用fillz 中的NA 值替换为最后一个可用值,并将z 替换为NA

      library(dplyr)
      library(tidyr)
      
      df %>%
        mutate(z = x) %>%
        group_by(i) %>%
        fill(z) %>%
        mutate(z = if(all(y == 0)) NA else z) %>%
        ungroup
      
      #      t     i     x     y     z
      #  <dbl> <dbl> <dbl> <dbl> <dbl>
      #1     1     1     3     0    NA
      #2     2     1     3     0    NA
      #3     3     1     2     0    NA
      #4     1     2     0     0     0
      #5     2     2    NA     1     0
      #6     3     2    NA     1     0
      #7     1     3     1     0     1
      #8     2     3     3     0     3
      #9     3     3    NA     1     3 
      

      【讨论】:

      • 我有一个后续问题:如何将 z 的所有值设置为 NA,除了 y 等于 1 的第一个时间点?所以 z 只包含从 0 到 1 变化的信息。z 则为:NA NA NA NA 0 NA NA NA 3
      • mutate(z = if(all(y == 0)) NA else z) 更改为mutate(z = replace(z, row_number() != match(1, y) | all(y == 0), NA))
      猜你喜欢
      • 2021-02-28
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多