如何将自定义函数应用于 R 中的特定列并避免“较长的对象长度不是较短对象长度的倍数”的问题?

How to apply a self-defined function to a specific column in R and avoid 'longer object length is not a multiple of shorter object length' problem?

提问人:cinnamoroll 提问时间:11/13/2023 最后编辑:cinnamoroll 更新时间:11/13/2023 访问量:30

问:

你好,祝阅读本文的人有美好的一天!

我正在尝试使用网格化数据(例如,lon、lat),目前正在弄清楚如何将我的值“四舍五入”到某个序列中最接近的值。

例如,我首先为网格化经度值创建一个序列:

lon_seq <- c(seq(120.125, 125.525, 0.05)) # a sequence of even distribution from 120.125 to 125.525

然后,我定义这个函数:

choose_lon <- function(lon_coord){
  lon2 <- lon_seq[which(abs(lon_seq - lon_coord) == min(abs(lon_seq - lon_coord)))][1]
  base::return(lon2)
}

如果我使用从外业工作中收集的数据运行,将从最接近我的数据的定义网格返回经度值(即 123.3729° 最接近 123.375°):

> choose_lon(123.3729)
[1] 123.375

但是,如果我尝试在数据帧中使用它,它将返回错误。这是一个示例数据帧和我尝试运行的代码:! longer object length is not a multiple of shorter object length

require(dplyr)

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 %>%
  dplyr::mutate(lon2 = choose_lon(lon))

上面的代码希望能用额外的经度值列来输出,这些经度值已根据我的“网格化”数据进行了相应的调整。

我试图按照指南从这里“延长”我的行,但到目前为止无济于事。

我希望恳请您就此事提供帮助。

非常感谢,愿你有美好的一天!

编辑:我为需要的dplyr添加了所需的代码。

r 函数 dplyr mutate

评论


答:

1赞 Ronak Shah 11/13/2023 #1

如果将两个值传递给函数,则可以重现相同的错误

choose_lon(c(123.3729, 1233.4036))
#[1] 123.325
Warning messages:

1: In lon_seq - lon_coord :
  longer object length is not a multiple of shorter object length
2: In lon_seq - lon_coord :
  longer object length is not a multiple of shorter object length

因此,这也是您的代码中发生的情况。将多个值传递给函数,其中函数只能接受一个值。若要在函数中一次只传递一个值,可以添加到代码中。rowwise()

library(dplyr)

df %>%
  dplyr::rowwise() %>%
  dplyr::mutate(lon2 = choose_lon(lon)) %>%
  data.frame() 

#  place code      lon    lon2
#1     A    1 123.4036 123.425
#2     B    1 123.7555 123.775
#3     C    2 120.6116 120.625
#4     D    3 124.6726 124.675
#5     E    2 122.3436 122.325

或者类似地,使用purrr::map_dbl

df %>% dplyr::mutate(lon2 = purrr::map_dbl(lon, choose_lon)) 

评论

0赞 cinnamoroll 11/13/2023
哦,如果将两个坐标传递给它,我无法测试该函数。我以前不熟悉,现在多亏了它,代码才能工作!谢谢!rowwise()