簡體   English   中英

R data.table 創建自定義 function 使用 lapply 創建和重新分配多個變量

[英]R data.table creating a custom function using lapply to create and reassign multiple variables

我有以下代碼行:

DT[flag==T, temp:=haz_1.5]
DT[, temp:= na.locf(temp, na.rm = FALSE), "pid"]
DT[agedays==61, haz_1.5_1:=temp]

我需要將其轉換為 function,以便它可以處理變量列表,而不僅僅是一個變量。 我最近學習了如何使用 lapply 創建 function,方法是傳遞列列表和創建一組新列的條件。 但是,當我通過列列表以及在這些列上傳遞變量的所有值時,我不確定如何執行此操作。

例如,我可以編寫以下代碼:

  columns<-c("haz_1.5", "waz_1.5")
  new_cols <- paste(columns, "1", sep = "_")
  x=61
  maled_anthro[(flag==TRUE)&(agedays==x), (new_cols) := lapply(.SD, function(y) na.locf(y,    na.rm=F)), .SDcols = columns] 

但是我錯過了 na.locf 步驟,因此在構建 function 之前,我沒有得到與原始代碼行相同的 output。 我如何將利用 na.locf 將值 (DT[, temp:= na.locf(temp, na.rm = FALSE), "pid"]) 合並到此 function 中的代碼行所有數據都包含在單個 function 中? 這會以同樣的方式與 lapply 一起工作嗎?

類似於我正在使用的數據表的虛擬數據:

DT <- data.table(pid  = c(1,1,2,3,3,4,4,5,5,5),
                 flag = c(T,T,F,T,T,F,T,T,T,T),
                 agedays = c(1,61,61,51,61,23,61,1,32,61),
                 haz_1.5 = c(1,1,1,2,NA,1,3,2,3,4),
                 waz_1.5 = c(1,NA,NA,NA,NA,2,2,3,4,4))

OP 的代碼可以轉換為匿名 function 應用於選定的columns

library(data.table)
columns <- c("haz_1.5", "waz_1.5")
new_cols <- paste0(columns, "_1")
x <-  61

DT[, (new_cols) := lapply(.SD, function(v) {
  temp <- fifelse(flag, v, NA_real_)
  temp <- nafill(temp, "locf")
  fifelse(agedays == x, temp, NA_real_)
}), .SDcols = columns, by = pid][]
 pid flag agedays haz_1.5 waz_1.5 haz_1.5_1 waz_1.5_1 1: 1 TRUE 1 1 1 NA NA 2: 1 TRUE 61 1 NA 1 1 3: 2 FALSE 61 1 NA NA NA 4: 3 TRUE 51 2 NA NA NA 5: 3 TRUE 61 NA NA 2 NA 6: 4 FALSE 23 1 2 NA NA 7: 4 TRUE 61 3 2 3 2 8: 5 TRUE 1 2 3 NA NA 9: 5 TRUE 32 3 4 NA NA 10: 5 TRUE 61 4 4 4 4

這與我們手動重復兩列的 OP 代碼時得到的結果相同(請注意,在通過引用部分分配之前需要清除temp列。)

DT[(flag), temp := haz_1.5]
DT[, temp := zoo::na.locf(temp, na.rm = FALSE), by = pid]
DT[agedays == 61, haz_1.5_1 := temp]
DT[, temp := NULL]
DT[(flag), temp := waz_1.5]
DT[, temp := zoo::na.locf(temp, na.rm = FALSE), by = pid]
DT[agedays == 61, waz_1.5_1 := temp]
DT[, temp := NULL][]
 pid flag agedays haz_1.5 waz_1.5 haz_1.5_1 waz_1.5_1 1: 1 TRUE 1 1 1 NA NA 2: 1 TRUE 61 1 NA 1 1 3: 2 FALSE 61 1 NA NA NA 4: 3 TRUE 51 2 NA NA NA 5: 3 TRUE 61 NA NA 2 NA 6: 4 FALSE 23 1 2 NA NA 7: 4 TRUE 61 3 2 3 2 8: 5 TRUE 1 2 3 NA NA 9: 5 TRUE 32 3 4 NA NA 10: 5 TRUE 61 4 4 4 4

一些解釋

  • OP 的“單列”代碼和這種方法之間有一個重要區別:匿名 function 為分組變量pid中的每個項目調用。 在 OP 的代碼中,第一個和最后一個分配正在處理未分組(完整)向量(這可能會更有效)。 但是,這些分配的結果與pid無關,結果是相同的。
  • 代替zoo::na.locf() ,使用 data.table 的nafill() function (新的 data.table v1.12.4,在 CRAN 2019 年 10 月 3 日)
  • DT[(flag), ...]等價於DT[flag == TRUE, ...]
  • 當使用fifelse()而不是通過引用分配子集時, no參數必須為NA才能符合要求。 因此, DT[, temp:= fifelse(flag, haz_1.5, NA_real_)][]等價於DT[(flag), temp:= haz_1.5][]

暫無
暫無

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

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