如何在R中为指定列应用自定义函数并解决长度不匹配报错
解决方法
问题原因
你定义的choose_lon函数仅支持单个数值输入,当通过mutate传入整个lon列(向量)时,abs(lon_seq - lon_coord)会生成一个行数为length(lon_seq)、列数为length(lon)的矩阵,后续min(abs(...))取的是整个矩阵的最小值,which返回的位置索引长度与输入向量不匹配,因此触发longer object length is not a multiple of shorter object length错误。
方案1:用sapply逐个处理向量元素
直接在mutate中用sapply遍历lon列的每个元素,调用原函数处理:
require(dplyr) lon_seq <- c(seq(120.125, 125.525, 0.05)) choose_lon <- function(lon_coord){ lon2 <- lon_seq[which(abs(lon_seq - lon_coord) == min(abs(lon_seq - lon_coord)))][1] base::return(lon2) } df <- data.frame( place = c('A', 'B', 'C', 'D', 'E'), code = c('1', '1', '2', '3', '2'), lon = c(123.4036, 123.7555, 120.6116, 124.6726, 122.3436) ) df2 <- df %>% mutate(lon2 = sapply(lon, choose_lon))
方案2:重写向量化函数(高效推荐)
由于lon_seq是等间隔序列(步长0.05,起始值120.125),可以通过数学计算直接得到最近值,无需遍历整个序列,效率大幅提升:
choose_lon_vec <- function(lon_coord) { # 计算与起始值的偏移量 offset <- lon_coord - 120.125 # 计算最近的步长数 nearest_step <- round(offset / 0.05) # 还原为序列中的对应值 120.125 + nearest_step * 0.05 } df2 <- df %>% mutate(lon2 = choose_lon_vec(lon))
验证:以123.4036为例,计算得123.425,与遍历lon_seq得到的最近值一致。
方案3:用rowwise逐行处理
如果偏好dplyr风格的逐行操作,可以用rowwise包裹:
df2 <- df %>% rowwise() %>% mutate(lon2 = choose_lon(lon)) %>% ungroup()
注意:该方法效率低于前两种,不建议处理大数据集。
内容的提问来源于stack exchange,提问作者cinnamoroll
相关产品推荐
相关产品推荐

