簡體   English   中英

根據另一個(時間)變量檢索第一個非 NA 值

[英]Retrieve first non NA value based on another (time) variable

目前正在處理一些時間序列數據,我想找到為個人記錄的每個變量的第一個值,其中有相當多的缺失數據。

我正在嘗試為小標題中的一系列變量中的每一個創建第一個(非 NA)值的摘要。 (我的大部分工作都使用 tidyverse 包,但很高興嘗試 data.table 或其他方法,我的已經是混合/混蛋))

示例數據:

     id  time  val1  val2
  <chr> <dbl> <dbl> <dbl>
1     a     2    NA     x
2     a     3     x    NA
3     b     1     y     y
4     b     3    NA     w
5     c     3    NA    NA
6     c     5     w     q

示例代碼:

tibble(
id = c(a,a,b,b,c,c), 
time=c(2,3,1,3,3,5), 
val1=c(NA,x,y,NA,NA,w), 
val2=c(x,NA,y,w,NA,q)) %>% 
group_by(id)%>%  
summarise(across(starts_with('val'), ~ .x[which.min(time)]))

但它也返回 NA 值。

# A tibble: 3 x 3
     id  val1  val2
  <chr> <chr> <chr>
1     a    NA     x
2     b     y     y
3     c    NA    NA

我希望的回報是:

# A tibble: 3 x 3
     id  val1  val2
  <chr> <chr> <chr>
1     a    x     x
2     b    y     y
3     c    w     q

自從 cross() 引入以來,我並沒有經常使用它。 但這似乎應該很簡單,我只是有點慢。 我嘗試在某個地方串一個 is.na() 似乎都失敗了,我試圖在很多變量中做到這一點。 因此我希望使用cross。

希望這是足夠的信息。 提前感謝您的幫助!

編輯:在我的實際數據中,時間變量是一個 dtrn 變量,但我也有 dttm 數據。

我相信以下內容可以實現您的目標。

df %>% summarise(across(starts_with('val'), ~ .x[!is.na(.x)][which.min(time)]))
# A tibble: 3 x 3
  id    val1  val2 
  <chr> <chr> <chr>
1 a     x     x    
2 b     y     y    
3 c     w     q   

另請參閱保持 imo 兩全其美的dtplyr解決方案:清晰的dplyr樣式語法,速度為data.table

df <- tibble(
  id = c('a','a','b','b','c','c'), 
  time=c(2,3,1,3,3,5), 
  val1=c(NA,'x','y',NA,NA,'w'), 
  val2=c('x',NA,'y','w',NA,'q')) 

# original sol ------------------------------------------------------------

df %>% 
  group_by(id) %>%  
  summarise(across(starts_with('val'), ~ .x[!is.na(.x)][which.min(time)]))

# dtplyr sol --------------------------------------------------------------

library(dtplyr)
df %>% lazy_dt %>% 
  group_by(id) %>%  
  summarise(across(starts_with('val'), ~ .x[!is.na(.x)][which.min(time)])) %>% 
  as_tibble()

然而,數據不夠大,無法看到此示例的時間改進。

基准測試

library(microbenchmark)
microbenchmark(
  dplyr = df %>% group_by(id) %>%  summarise(across(starts_with('val'), ~ .x[!is.na(.x)][which.min(time)])),
  dtplyr = df %>% lazy_dt %>% group_by(id) %>%  summarise(across(starts_with('val'), ~ .x[!is.na(.x)][which.min(time)]))
)
Unit: milliseconds
   expr    min      lq     mean  median     uq     max neval
  dplyr 4.7532 5.18185 5.733455 5.42160 5.5945 22.7650   100
 dtplyr 4.7024 5.09795 5.428136 5.27685 5.5639 10.7739   100

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM