R:如何通过ID识别多个列的第一个积极观察日期?

R:如何通过ID识别多个列的第一个积极观察日期?,r,R,我想通过ID为多个列确定积极观察的第一个日期 数据帧示例: ID date Observ1 Observ2 Observ3 1 1 1 0 0 1 2 0 1 0 1 3 1 0 1 2 1 1 1 0 预期结果: ID FirstObserv1 FirstObserv2 FirstObserv3

我想通过ID为多个列确定积极观察的第一个日期

数据帧示例:

ID  date  Observ1 Observ2 Observ3
 1     1        1       0       0
 1     2        0       1       0
 1     3        1       0       1
 2     1        1       1       0 
预期结果:

ID  FirstObserv1 FirstObserv2 FirstObserv3
 1             1            2            3
 2             1            1           NA
对于单列观测,我可以用dplyr解决:

df %>% group_by(ID) %>% filter( Observ1 > 0) %>% summarize( FirstObserv1 = min(date) ) %>% as.data.frame()

但是,我不知道如何一次对多个列执行此操作。

请尝试使用tidyverse函数对数据进行如下整形。代码id的键过滤值为1的值,然后设置过滤器以使用过滤器提取最小日期值。之后,你重塑到宽,你得到了预期的输出。代码如下:

library(tidyverse)
#Code
dfnew <- df %>% pivot_longer(-c(ID,date)) %>%
  group_by(ID) %>%
  filter(value==1) %>% select(-value) %>% ungroup() %>%
  group_by(ID,name) %>%
  filter(date==min(date)) %>%
  pivot_wider(names_from = name,values_from=date)
输出:

# A tibble: 2 x 4
# Groups:   ID [2]
     ID Observ1 Observ2 Observ3
  <int>   <int>   <int>   <int>
1     1       1       2       3
2     2       1       1      NA
使用的一些数据:

#Data
df <- structure(list(ID = c(1L, 1L, 1L, 2L), date = c(1L, 2L, 3L, 1L
), Observ1 = c(1L, 0L, 1L, 1L), Observ2 = c(0L, 1L, 0L, 1L), 
    Observ3 = c(0L, 0L, 1L, 0L)), class = "data.frame", row.names = c(NA, 
-4L))

尝试使用tidyverse函数像这样重塑数据。代码id的键过滤值为1的值,然后设置过滤器以使用过滤器提取最小日期值。之后,你重塑到宽,你得到了预期的输出。代码如下:

library(tidyverse)
#Code
dfnew <- df %>% pivot_longer(-c(ID,date)) %>%
  group_by(ID) %>%
  filter(value==1) %>% select(-value) %>% ungroup() %>%
  group_by(ID,name) %>%
  filter(date==min(date)) %>%
  pivot_wider(names_from = name,values_from=date)
输出:

# A tibble: 2 x 4
# Groups:   ID [2]
     ID Observ1 Observ2 Observ3
  <int>   <int>   <int>   <int>
1     1       1       2       3
2     2       1       1      NA
使用的一些数据:

#Data
df <- structure(list(ID = c(1L, 1L, 1L, 2L), date = c(1L, 2L, 3L, 1L
), Observ1 = c(1L, 0L, 1L, 1L), Observ2 = c(0L, 1L, 0L, 1L), 
    Observ3 = c(0L, 0L, 1L, 0L)), class = "data.frame", row.names = c(NA, 
-4L))

这里有一种方法,如果观察结果是肯定的,则用日期替换观察结果,反之亦然。获得每次观察的最小值会产生期望的结果

df %>%
  mutate_at(vars(starts_with("Observ")), ~ifelse(. > 0, date, NA)) %>%
  group_by(ID) %>%
  summarise_at(vars(starts_with("Observ")), min, na.rm = TRUE)
#> # A tibble: 2 x 4
#>      ID Observ1 Observ2 Observ3
#>   <dbl>   <dbl>   <dbl>   <dbl>
#> 1     1       1       2       3
#> 2     2       1       1     Inf

这里有一种方法,如果观察结果是肯定的,则用日期替换观察结果,反之亦然。获得每次观察的最小值会产生期望的结果

df %>%
  mutate_at(vars(starts_with("Observ")), ~ifelse(. > 0, date, NA)) %>%
  group_by(ID) %>%
  summarise_at(vars(starts_with("Observ")), min, na.rm = TRUE)
#> # A tibble: 2 x 4
#>      ID Observ1 Observ2 Observ3
#>   <dbl>   <dbl>   <dbl>   <dbl>
#> 1     1       1       2       3
#> 2     2       1       1     Inf
另一种选择:

df %>% 
  group_by(ID) %>% 
  summarise(across(
    -date, 
    list(First = ~{x <- which(. > 0); if (length(x) > 0L) date[[x[[1L]]]] else NA_real_}), 
    .names = "{.fn}{.col}"
  ))
输出

     ID FirstObserv1 FirstObserv2 FirstObserv3
  <dbl>        <dbl>        <dbl>        <dbl>
1     1            1            2            3
2     2            1            1           NA
另一种选择:

df %>% 
  group_by(ID) %>% 
  summarise(across(
    -date, 
    list(First = ~{x <- which(. > 0); if (length(x) > 0L) date[[x[[1L]]]] else NA_real_}), 
    .names = "{.fn}{.col}"
  ))
输出

     ID FirstObserv1 FirstObserv2 FirstObserv3
  <dbl>        <dbl>        <dbl>        <dbl>
1     1            1            2            3
2     2            1            1           NA
我们可以使用data.table

或者使用tidyverse

数据 我们可以使用data.table

或者使用tidyverse

数据
好的一只鸭子,同样的方法直到filtervalue==1,但是被卡住了。陡峭的学习曲线。@KarthikS肯定!!!所有的一切都是关于学习曲线:好的一只鸭子,同样的方法直到filtervalue==1,但被卡住了。陡峭的学习曲线。@KarthikS肯定!!!一切都是关于学习曲线的:这不是最后一个参数。groups='drop'默认值吗?例如:>df%>%group\U byID%>%SUMMARESEARCROSSSTARTS\U与'Obser',~哪个。>0[1],.names='First{col}%>%group\u vars使用.groups参数character0>df%>%group\u byID%>%summarySeaCrossStart\u使用'Obser',~which.>0[1],.names='First{col}',.groups='drop%>%group_vars character0>都提供相同的输出。请您帮助理解明确提到.groups='drop'参数的意义。@KarthikS'drop\u last'不是最后一个参数。groups='drop'默认值?例如:>df%>%group\U byID%>%SUMMARESEARCROSSSTARTS\U与'Obser',~哪个。>0[1],.names='First{col}%>%group\u vars使用.groups参数character0>df%>%group\u byID%>%summarySeaCrossStart\u使用'Obser',~which.>0[1],.names='First{col}',.groups='drop%>%group_vars character0>都提供相同的输出。请您帮助理解明确提到.groups='drop'参数的意义。@KarthikS它是'drop\u last'我喜欢这个解决方案,因为它看起来很干净,并且避免了多次重塑数据。我对此唯一的不满是,NAs将被min视为Inf,有没有办法防止这种情况发生?min的行为无法改变。唯一的方法是添加另一个步骤,用NA替换Inf。我喜欢这个解决方案,因为它看起来很干净,并且避免了多次重塑数据。我对此唯一的不满是,NAs将被min视为Inf,有没有办法防止这种情况发生?min的行为无法改变。唯一的方法是添加另一个步骤,用NA替换Inf。