提问人:cinnamoroll 提问时间:11/13/2023 最后编辑:cinnamoroll 更新时间:11/13/2023 访问量:30
如何将自定义函数应用于 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?
问:
你好,祝阅读本文的人有美好的一天!
我正在尝试使用网格化数据(例如,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添加了所需的代码。
答:
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()
评论