在tibble上应用自定义函数时遭遇掩码问题求助
问题原因
你的函数get_wsa是为标量输入设计的——当传入单个数值时,filter能精准匹配wsa_tab中的单行数据。但直接传入tibble的列(向量)时,filter会尝试用整个向量去匹配wsa_tab的所有行,导致没有任何行能同时满足draught == 整个draught_m向量和trim == 整个trim_m向量,最终返回长度为0的空向量,而mutate要求新列的长度必须等于原数据的行数(3)或1,因此触发错误。
解决方案
以下三种方法都能解决问题,按tidyverse风格推荐优先级排序:
方法1:用数据框连接(最高效)
直接通过left_join将两个表按匹配字段关联,无需自定义函数:
require("tidyverse") wsa <- tibble("trim" = c(4, 4, 4, 5, 5, 5, 6, 6, 6), "draught" = c(7, 8, 9, 7, 8, 9, 7, 8, 9), "wsa" = c(100, 200, 300, 400, 500, 600, 700, 800, 900)) data <- tibble("draught_m" = c(6, 5, 4), "trim_m" = c(9, 8, 7)) data2 <- data %>% left_join(wsa, by = c("draught_m" = "draught", "trim_m" = "trim")) %>% rename(wsa_m2 = wsa)
注:如果某些匹配项不存在,wsa_m2会显示NA,符合数据处理的常规逻辑。
方法2:用rowwise()逐行处理
让mutate逐行调用你的函数,每次传入单个标量值:
data2 <- data %>% rowwise() %>% mutate(wsa_m2 = get_wsa(draught_m, trim_m, wsa_tab = wsa)) %>% ungroup()
处理完成后记得用ungroup()取消分组状态,避免后续操作受影响。
方法3:用purrr::map2向量化处理
利用purrr的map2_dbl函数,逐对处理draught_m和trim_m的元素:
data2 <- data %>% mutate(wsa_m2 = map2_dbl(draught_m, trim_m, ~get_wsa(.x, .y, wsa_tab = wsa)))
map2_dbl会自动将每一对元素传入函数,并返回数值型向量作为新列。
内容的提问来源于stack exchange,提问作者Gnihilo
相关产品推荐
相关产品推荐

