如何在R的dplyr管道mutate中使用hashmap的query函数?
解决dplyr中hashmap批量查询的mutate错误
问题重现
你想用hashmap快速查找值并结合dplyr管道计算新列,避免for循环,但运行代码时出现错误。代码如下:
data("mtcars") m.subset <- mtcars[2:7, 10:11] letters <- c("a", "b", "c", "d", "e", "f") m.subset <- cbind(m.subset, letters) testmap <- hashmap() testmap[c("a", "b", "c", "d", "e", "f")] <- c(4.0, 5.0, 6.0, 7.0, 8.0, 9.0) m.subset %>% mutate(score1=query(testmap, letters)*gear) -> m.subset
错误信息:
Error in `mutate()`: ! Problem while computing `score1 = query(testmap, letters) * gear`. ✖ `score1` must be size 6 or 1, not 0. Run `rlang::last_error()` to see where the error occurred.
问题原因
- 变量名冲突:你把数据框的列命名为
letters,但letters是R内置的全局变量(包含26个小写字母),所以在mutate中调用letters时,并没有引用数据框里的列,而是调用了全局的26字母向量,导致hashmap查询了不存在的键,返回空值。 - hashmap批量查询的返回结构:
hashmap包的query函数处理向量键时,返回的不是可直接运算的向量,无法和gear列直接相乘。
解决方案
方案1:修复变量名+使用hashmap索引
先修改列名避免冲突,再用hashmap的索引语法直接获取向量值:
data("mtcars") m.subset <- mtcars[2:7, 10:11] letter_col <- c("a", "b", "c", "d", "e", "f") m.subset <- cbind(m.subset, letter_col) testmap <- hashmap() testmap[c("a", "b", "c", "d", "e", "f")] <- c(4.0, 5.0, 6.0, 7.0, 8.0, 9.0) # 使用索引方式获取值向量,直接计算 m.subset %>% mutate(score1 = testmap[letter_col] * gear) -> m.subset
方案2:用purrr批量查询
如果坚持用query函数,可以用purrr::map_vec遍历每个元素查询,返回向量后计算:
library(purrr) data("mtcars") m.subset <- mtcars[2:7, 10:11] letter_col <- c("a", "b", "c", "d", "e", "f") m.subset <- cbind(m.subset, letter_col) testmap <- hashmap() testmap[c("a", "b", "c", "d", "e", "f")] <- c(4.0, 5.0, 6.0, 7.0, 8.0, 9.0) # 逐个查询并返回向量 m.subset %>% mutate(score1 = map_vec(letter_col, ~ query(testmap, .x)) * gear) -> m.subset
方案3:改用dplyr关联(无需hashmap)
如果不一定要用hashmap,用dplyr的left_join更直观,适合新手:
data("mtcars") m.subset <- mtcars[2:7, 10:11] letter_col <- c("a", "b", "c", "d", "e", "f") m.subset <- cbind(m.subset, letter_col) # 把映射关系做成数据框 map_df <- data.frame( letter_col = c("a", "b", "c", "d", "e", "f"), value = c(4.0, 5.0, 6.0, 7.0, 8.0, 9.0) ) # 关联后计算 m.subset %>% left_join(map_df, by = "letter_col") %>% mutate(score1 = value * gear) %>% select(-value) -> m.subset
内容的提问来源于stack exchange,提问作者Marja van der Wind
相关产品推荐
相关产品推荐

