查找的链接因素 - 这是最有效的方法吗?
Chaining factors for lookup - is this the most efficient way?
我有两个因素用作查找表:
iState <- list("A" = "Alaska", "T" = "Texas", "G" = "Georgia")
sCap <- list("Alaska" = "Juneau", "Texas" = "Austin", "Georgia" = "Atlanta")
以及要查找的向量:
foo <- c("T", "G", "A", "B", NA)
此代码将它们链接在一起并提供我想要的查找:
sCap[iState[foo] %>% as.character() %>% na_if("NULL") ] %>% as.character() %>% na_if("NULL")
# [1] "Austin" "Atlanta" "Juneau" NA NA
这是将这些因素联系在一起的最节省执行时间的方法吗?或者有更好的方法吗?
它可能不是很快,尤其是因为使用了函数 %>%
和 na_if()
。
我不确定这是否是最快的方法,但是如果您只是将 sCap
和 iState
变成原子向量而不是列表(使用 c()
而不是 list()
), 你可以很容易地得到你想要的:
iState <- c(A = "Alaska", T = "Texas", G = "Georgia")
sCap <- c(Alaska = "Juneau", Texas = "Austin", Georgia = "Atlanta")
foo <- c("T", "G", "A", "B", NA)
sCap[iState[foo]]
# Texas Georgia Alaska <NA> <NA>
# "Austin" "Atlanta" "Juneau" NA NA
如果结果未命名对您很重要,您可以使用 unname()
:
unname(sCap[iState[foo]])
如果使用查找向量而不是查找列表,您可以做得更好。基本上,我把list
改成c()
,然后把as.character
位全部删掉。
vState <- c("A" = "Alaska", "T" = "Texas", "G" = "Georgia")
vCap <- c("Alaska" = "Juneau", "Texas" = "Austin", "Georgia" = "Atlanta")
vCap[vState[foo]]
到目前为止的基准测试方法:
microbenchmark::microbenchmark(
recode = foo %>%
dplyr::recode(!!!iState, .default = NA_character_) %>%
dplyr::recode(!!!sCap, .default = NA_character_),
lists = sCap[iState[foo] %>% as.character() %>% na_if("NULL") ] %>% as.character() %>% na_if("NULL"),
lists_no_pipe = na_if(as.character(sCap[na_if(as.character(iState[foo]), "NULL")]), "NULL"),
vectors = unname(vCap[vState[foo]])
)
# Unit: microseconds
# expr min lq mean median uq max neval
# recode 227.1 244.05 305.203 268.05 319.55 591.1 100
# lists 182.2 198.85 244.964 222.10 254.20 562.6 100
# lists_no_pipe 11.4 13.25 17.726 15.45 18.70 64.5 100
# vectors 2.5 3.85 5.269 4.90 6.40 12.9 100
如果您希望事情尽可能快,请不要使用 %>%
- 这是额外的开销。如果您正在做复杂的事情,那么管道的额外微秒并不重要。但在这种情况下,正在完成的操作已经非常快,以至于几微秒的管道实际上占了执行时间的很大一部分。
您可以走得更快——尤其是如果您的查找表很大,可以改为使用键控 data.table
的连接。
有些人可能会觉得这很傻,但我喜欢 dplyr::recode
:
foo %>%
dplyr::recode(!!!iState, .default = NA_character_) %>%
dplyr::recode(!!!sCap, .default = NA_character_)
[1] "Austin" "Atlanta" "Juneau" NA NA
它适用于列表或向量。
我有两个因素用作查找表:
iState <- list("A" = "Alaska", "T" = "Texas", "G" = "Georgia")
sCap <- list("Alaska" = "Juneau", "Texas" = "Austin", "Georgia" = "Atlanta")
以及要查找的向量:
foo <- c("T", "G", "A", "B", NA)
此代码将它们链接在一起并提供我想要的查找:
sCap[iState[foo] %>% as.character() %>% na_if("NULL") ] %>% as.character() %>% na_if("NULL")
# [1] "Austin" "Atlanta" "Juneau" NA NA
这是将这些因素联系在一起的最节省执行时间的方法吗?或者有更好的方法吗?
它可能不是很快,尤其是因为使用了函数 %>%
和 na_if()
。
我不确定这是否是最快的方法,但是如果您只是将 sCap
和 iState
变成原子向量而不是列表(使用 c()
而不是 list()
), 你可以很容易地得到你想要的:
iState <- c(A = "Alaska", T = "Texas", G = "Georgia")
sCap <- c(Alaska = "Juneau", Texas = "Austin", Georgia = "Atlanta")
foo <- c("T", "G", "A", "B", NA)
sCap[iState[foo]]
# Texas Georgia Alaska <NA> <NA>
# "Austin" "Atlanta" "Juneau" NA NA
如果结果未命名对您很重要,您可以使用 unname()
:
unname(sCap[iState[foo]])
如果使用查找向量而不是查找列表,您可以做得更好。基本上,我把list
改成c()
,然后把as.character
位全部删掉。
vState <- c("A" = "Alaska", "T" = "Texas", "G" = "Georgia")
vCap <- c("Alaska" = "Juneau", "Texas" = "Austin", "Georgia" = "Atlanta")
vCap[vState[foo]]
到目前为止的基准测试方法:
microbenchmark::microbenchmark(
recode = foo %>%
dplyr::recode(!!!iState, .default = NA_character_) %>%
dplyr::recode(!!!sCap, .default = NA_character_),
lists = sCap[iState[foo] %>% as.character() %>% na_if("NULL") ] %>% as.character() %>% na_if("NULL"),
lists_no_pipe = na_if(as.character(sCap[na_if(as.character(iState[foo]), "NULL")]), "NULL"),
vectors = unname(vCap[vState[foo]])
)
# Unit: microseconds
# expr min lq mean median uq max neval
# recode 227.1 244.05 305.203 268.05 319.55 591.1 100
# lists 182.2 198.85 244.964 222.10 254.20 562.6 100
# lists_no_pipe 11.4 13.25 17.726 15.45 18.70 64.5 100
# vectors 2.5 3.85 5.269 4.90 6.40 12.9 100
如果您希望事情尽可能快,请不要使用 %>%
- 这是额外的开销。如果您正在做复杂的事情,那么管道的额外微秒并不重要。但在这种情况下,正在完成的操作已经非常快,以至于几微秒的管道实际上占了执行时间的很大一部分。
您可以走得更快——尤其是如果您的查找表很大,可以改为使用键控 data.table
的连接。
有些人可能会觉得这很傻,但我喜欢 dplyr::recode
:
foo %>%
dplyr::recode(!!!iState, .default = NA_character_) %>%
dplyr::recode(!!!sCap, .default = NA_character_)
[1] "Austin" "Atlanta" "Juneau" NA NA
它适用于列表或向量。