R:使用带 grepl 条件的 if 语句处理列中的数据
R: Processing data in columns using if statements with grepl conditioning
longtidue <- c('517W', '595W', '433W', '450E', '659E', '682W', '678W', '546E', '462W', '500W')
latitude <- c('291N','202N', '276N', '269S', '279N', '294N', '252N', '254S', '248N', '258N')
df <- data.frame(latitude, longitude)
是我正在使用的数据库的一个示例,它处理以以下格式出现的纬度和经度坐标:
240N, 707W, 267S, 130E
我需要处理这些坐标,以便它们可以用在采用以下形式坐标的模型中:
24.0, -70.7, -26.7, 13.0
(在模型中,北和东被认为是正方向。)
目标是能够 运行 向下查看整列,并确定单元格中是否存在 "N" 或 "S"。我想从那里删除字母,然后将剩余的数字除以 10 或 -10 以给出正确的符号。如果 N 或 S 都没有出现在列中,我希望代码单独保留单元格,这就是我在下面发布的示例代码末尾的 else 语句的原因。为了处理列中的所有数据,我尝试使用 elseif 语句,但我不确定如何让它工作。我最终进入了一个 for 循环,if 条件看起来像这样:
for (i in 1:nrow(df)) {
if (grepl("N",df$latitude, fixed = TRUE)) {
df$latitude <- gsub("N", "",df$latitude) & df$latitude <- df$latitude/(10)
} else if (grepl("S",df$latitude, fixed = TRUE)) {
df$latitude <- gsub("S", "",df$latitude) & df$latitude <- as.numeric(df$latitude) & df$latitude <- df$latitude/(-10)
} else (df$latitude)
}
但这要么给我一个错误 df$latitude/(10) 说 "non-numeric argument to binary operator" 从数据从字符到数字的转换(?) and/or 一个警告 "the condition has length > 1 and only the first element will be used"。我对 R 和堆栈溢出也很陌生,所以如果我的代码可以更好地格式化,请告诉我。
提前致谢!
这是一个基本的 R 选项。首先,我们可以通过剥离最后一个方向字符,转换为数字,然后除以 10 来计算 latitude/longitude 值的绝对值。然后,我们有条件地翻转西方向和南方向的符号。
lng <- as.numeric(sub(".$", "", longitude)) / 10
lng <- ifelse(grepl("[WS]$", longitude), -1.0, 1.0) * lng
lng
[1] -51.7 -59.5 -43.3 45.0 65.9 -68.2 -67.8 54.6 -46.2 -50.0
数据:
longitude <- c('517W', '595W', '433W', '450E', '659E', '682W', '678W', '546E', '462W', '500W')
您遇到了一些问题:
正如我在评论中提到的,您从 1
循环 i
到 nrow(df)
。但是你没有在循环中提到 i
,所以你在相同的输入上一次又一次地 运行 相同的代码。要成功使用 for
循环,您需要在其中放置一堆 [i]
,以便一次处理每个输入和输出。
上面的循环方法很复杂,因为一个列只能有一种类型,所以你不能将 character
或 factor
列转换为 numeric
一次一行---必须全有或全无。
你好像对&
有很大的误解。这行代码没有意义:df$latitude <- gsub("N", "",df$latitude) & df$latitude <- df$latitude/(10)
,它是用 &
连接在一起的两行代码。 A & B
并不意味着 "do A
and do B
",它的意思是“检查 A
和 B
是否都为真。Return TRUE
如果它们是,和 FALSE
否则。如果你想做 A
然后做 B
,只需将 A
放在一行上,然后 B
下一行
至于 好的 解决方案,在我写这篇文章时,您已经从 Tim 那里收到了一个不错的、简短的、矢量化的(不需要循环)解决方案。就这么做吧。
longtidue <- c('517W', '595W', '433W', '450E', '659E', '682W', '678W', '546E', '462W', '500W')
latitude <- c('291N','202N', '276N', '269S', '279N', '294N', '252N', '254S', '248N', '258N')
df <- data.frame(latitude, longitude)
是我正在使用的数据库的一个示例,它处理以以下格式出现的纬度和经度坐标:
240N, 707W, 267S, 130E
我需要处理这些坐标,以便它们可以用在采用以下形式坐标的模型中:
24.0, -70.7, -26.7, 13.0
(在模型中,北和东被认为是正方向。)
目标是能够 运行 向下查看整列,并确定单元格中是否存在 "N" 或 "S"。我想从那里删除字母,然后将剩余的数字除以 10 或 -10 以给出正确的符号。如果 N 或 S 都没有出现在列中,我希望代码单独保留单元格,这就是我在下面发布的示例代码末尾的 else 语句的原因。为了处理列中的所有数据,我尝试使用 elseif 语句,但我不确定如何让它工作。我最终进入了一个 for 循环,if 条件看起来像这样:
for (i in 1:nrow(df)) {
if (grepl("N",df$latitude, fixed = TRUE)) {
df$latitude <- gsub("N", "",df$latitude) & df$latitude <- df$latitude/(10)
} else if (grepl("S",df$latitude, fixed = TRUE)) {
df$latitude <- gsub("S", "",df$latitude) & df$latitude <- as.numeric(df$latitude) & df$latitude <- df$latitude/(-10)
} else (df$latitude)
}
但这要么给我一个错误 df$latitude/(10) 说 "non-numeric argument to binary operator" 从数据从字符到数字的转换(?) and/or 一个警告 "the condition has length > 1 and only the first element will be used"。我对 R 和堆栈溢出也很陌生,所以如果我的代码可以更好地格式化,请告诉我。
提前致谢!
这是一个基本的 R 选项。首先,我们可以通过剥离最后一个方向字符,转换为数字,然后除以 10 来计算 latitude/longitude 值的绝对值。然后,我们有条件地翻转西方向和南方向的符号。
lng <- as.numeric(sub(".$", "", longitude)) / 10
lng <- ifelse(grepl("[WS]$", longitude), -1.0, 1.0) * lng
lng
[1] -51.7 -59.5 -43.3 45.0 65.9 -68.2 -67.8 54.6 -46.2 -50.0
数据:
longitude <- c('517W', '595W', '433W', '450E', '659E', '682W', '678W', '546E', '462W', '500W')
您遇到了一些问题:
正如我在评论中提到的,您从
1
循环i
到nrow(df)
。但是你没有在循环中提到i
,所以你在相同的输入上一次又一次地 运行 相同的代码。要成功使用for
循环,您需要在其中放置一堆[i]
,以便一次处理每个输入和输出。上面的循环方法很复杂,因为一个列只能有一种类型,所以你不能将
character
或factor
列转换为numeric
一次一行---必须全有或全无。你好像对
&
有很大的误解。这行代码没有意义:df$latitude <- gsub("N", "",df$latitude) & df$latitude <- df$latitude/(10)
,它是用&
连接在一起的两行代码。A & B
并不意味着 "doA
and doB
",它的意思是“检查A
和B
是否都为真。ReturnTRUE
如果它们是,和FALSE
否则。如果你想做A
然后做B
,只需将A
放在一行上,然后B
下一行
至于 好的 解决方案,在我写这篇文章时,您已经从 Tim 那里收到了一个不错的、简短的、矢量化的(不需要循环)解决方案。就这么做吧。