有這塊,我想在一個函數評估函數的參數傳遞給data.table
indata <- data.frame(id = c(1L, 2L, 3L, 4L, 12L, 13L, 14L, 15L),
fid = c(NA, 9L, 1L, 1L, 7L, 5L, 5L, 5L),
mid = c(0L, NA, 2L, 2L, 6L, 6L, 6L, 8L))
library(data.table)
DT <- as.data.table(indata)
DT[, msib:=.(list(id)), by = mid][
,msibs := mapply(setdiff, msib, id)][
,fsib := .(list(id)), by = fid][
,fsibs := mapply(setdiff, fsib, id)][
,siblist := mapply(union, msibs, fsibs)][
,c("msib","msibs", "fsib", "fsibs") := NULL]
到目前爲止好包裝代碼。按需要工作。現在它應該被封裝在一個函數中,我可以通過替代變量名稱(如果可能,不用引用),這是我的第一次嘗試。
f <- function(DT, id, fid, mid) {
DT[, msib:=.(list(id)), by = mid][
,msibs := mapply(setdiff, msib, id)][
,fsib := .(list(id)), by = fid][
,fsibs := mapply(setdiff, fsib, id)][
,siblist := mapply(union, msibs, fsibs)][
,c("msib","msibs", "fsib", "fsibs") := NULL]
}
我知道這是行不通的,但讓我們看看它的錯誤拋出as.vector
indata2 <- indata
names(indata2) <- c("A", "B", "C") # Give new names
DT2 <- as.data.table(indata2)
f(DT2, A, B, C)
錯誤(X, 「列表」): 不能強迫型'封'到類型'列表'的向量
這很有道理。現在要確保承諾正確評估我試過這個
f <- function(DT, id, fid, mid) {
mid <- deparse(substitute(mid))
id <- deparse(substitute(id))
fid <- deparse(substitute(fid))
DT[, msib:=.(list(id)), by = mid][
,msibs := mapply(setdiff, msib, id)][
,fsib := .(list(id)), by = fid][
,fsibs := mapply(setdiff, fsib, id)][
,siblist := mapply(union, msibs, fsibs)][
,c("msib","msibs", "fsib", "fsibs") := NULL]
}
這不會引發錯誤,但也不起作用。輸出看起來像這樣
f(DT2, A, B, C)
A B C siblist
1: 1 NA 0
2: 2 9 NA
3: 3 1 2
4: 4 1 2
5: 12 7 6
6: 13 5 6
7: 14 5 6
8: 15 5 8
和siblist
欄是空的,它不應該是,不,當我手動運行它。我也試過這個版本(其轉換爲字符串),看看是否能工作:
f <- function(DT, id, fid, mid){
mid <- as.character(substitute(mid))
id <- as.character(substitute(id))
fid <- as.character(substitute(fid))
DT[, msib:=.(list(id)), by = mid][ # Siblings through the mother
,msibs := mapply(setdiff, msib, id)][
,fsib := .(list(id)), by = fid][
,fsibs := mapply(setdiff, fsib, id)][
,siblist := mapply(union, msibs, fsibs)][
,c("msib","msibs", "fsib", "fsibs") := NULL] # Removed unused
}
但是,這並不工作,要麼 - 相同的輸出上面。我認爲這可能是因爲data.table
的j
部分中的承諾在錯誤的環境中評估,但我不確定。我如何解決我的功能?
注意事項「迄今爲止很好」,列表列非常低效。你可能想看看igraph軟件包或其他專門用於這類數據的東西(包括個人之間的鏈接和其他東西)。假設你不介意低效率,一個快速的解決辦法是使'DT = setnames(copy(DT),c(mid,id,fid),c(「mid」,「id」,「fid」))在你的deparse/substitute/etc之後,對嗎? – Frank
這會工作,但我需要處理20+ mio邊緣的數據集,所以我不想創建額外的數據副本。我很想聽聽有關生成最終列表的其他選項。我早就涉及這個問題的不同軟件包之間的時序問題做了一些嘗試,並發現'data.table'出來的速度很快,但我很想獲得其他方法的想法。 – ekstroem