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

问题描述 投票:0回答:1

读这篇文章的人你好,美好的一天!

我正在尝试使用网格数据(例如经度、纬度),目前正在研究如何将我的值“舍入”为特定序列中最接近的值。

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

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 function dplyr mutate
1个回答
0
投票

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

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)) 
© www.soinside.com 2019 - 2024. All rights reserved.