R :: 在 r 中将字符串从 "x,y" 反转为 "y,x"
R:: reverse a string from "x,y" to "y,x" in r
我有一个table这样的
aa<-tribble(
~"a",~"b",~"c",~"d",
" 78.1445111, 9.9365072", "78.1444646, 9.9365044", " 78.1445111, 9.9365072", "78.1444646, 9.9365044",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
)
这些是“纬度、经度”值。我想将它们转换成“long, lat”。例如,我想将“78.1445111, 9.9365072”转换为“9.9365072,78.1445111”。在 r 中是否可以对所有列进行自动化?
我希望在所有列中都有这样的输出:
a<- tribble(
~"a",~"b",~"c",~"d",
"9.9365072,78.1445111", "9.9365044,78.1444646,", "9.9365072,78.1445111", "9.9365044,78.1444646,",
"9.9365166,78.1444197", "9.9365422,78.1443816",
"9.9365748,78.142359", "9.9366057,78.1421918",
"9.9366057,78.1421918", "9.9367106,78.1419488",
"9.9365166,78.1444197", "9.9365422,78.1443816",
"9.9365748,78.142359", "9.9366057,78.1421918",
"9.9366057,78.1421918", "9.9367106,78.1419488"
)
我试过但失败了:
bag_1<-list()
for(i in colnames(a)){
dummy <-str_split_fixed(a[[i]], ",", 2)
bag_1[[i]]<-dummy
dum<-do.call(rbind,bag_1)
}
这样可以吗?使用 dplyr
和 tidyr
函数
library(tidyverse)
aa %>% mutate(id = row_number()) %>%
pivot_longer(cols = -id) %>%
separate(value, into = c("Lat", "Long"), sep = ", ") %>%
mutate(new = paste(Long, Lat, sep = ", ")) %>%
select(-Lat, -Long) %>%
pivot_wider(id_cols = id, names_from = name, values_from = new)
# A tibble: 4 x 5
id a b c d
<int> <chr> <chr> <chr> <chr>
1 1 9.9365072, 78.1445111 9.9365044, 78.1444646 9.9365072, 78.1445111 9.9365044, 78.1444646
2 2 9.9365166, 78.1444197 9.9365422, 78.1443816 9.9365748, 78.142359 9.9366057, 78.1421918
3 3 9.9366057, 78.1421918 9.9367106, 78.1419488 9.9365166, 78.1444197 9.9365422, 78.1443816
4 4 9.9365748, 78.142359 9.9366057, 78.1421918 9.9366057, 78.1421918 9.9367106, 78.1419488
aa
使用
aa <- tribble(
~"a",~"b",~"c",~"d",
"78.1445111, 9.9365072", "78.1444646, 9.9365044", "78.1445111, 9.9365072", "78.1444646, 9.9365044",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
)
在 Base R
中,您可以颠倒每列 strsplit()
字符向量的顺序:
sapply(aa, function(x){
# first strsplit
tmp1 <- strsplit(x, ", ", fixed = T)
# reverse and paste
sapply(tmp1, function(z){
paste(rev(z), collapse = ", ")
})
})
# yields
# a b c d
# [1,] "9.9365072, 78.1445111" "9.9365044, 78.1444646" "9.9365072, 78.1445111" "9.9365044, 78.1444646"
# [2,] "9.9365166, 78.1444197" "9.9365422, 78.1443816" "9.9365748, 78.142359" "9.9366057, 78.1421918"
# [3,] "9.9366057, 78.1421918" "9.9367106, 78.1419488" "9.9365166, 78.1444197" "9.9365422, 78.1443816"
# [4,] "9.9365748, 78.142359" "9.9366057, 78.1421918" "9.9366057, 78.1421918" "9.9367106, 78.1419488"
你可以用 dplyr::mutate 和 stringr::str_replace:
# across all column
aa %>% mutate(across(everything(),
# capture the non-comma characters into 2 groups
~ str_replace((.),"([^,]+),([^,]+)",
# switch first and second capture groups around
"\2,\1")))
基础 R 选项:
编写一个函数来反转字符串:
reverse_string <- function(x) {
trimws(paste(sub('.*,', '', x), sub(',.*', '', x), sep = ','))
}
使用 lapply
对每一列应用它。
aa[] <- lapply(aa, reverse_string)
aa
# A tibble: 4 x 4
# a b c d
# <chr> <chr> <chr> <chr>
#1 9.9365072, 78.1445111 9.9365044,78.1444646 9.9365072, 78.1445111 9.9365044,78.1444646
#2 9.9365166,78.1444197 9.9365422,78.1443816 9.9365748,78.142359 9.9366057,78.1421918
#3 9.9366057,78.1421918 9.9367106,78.1419488 9.9365166,78.1444197 9.9365422,78.1443816
#4 9.9365748,78.142359 9.9366057,78.1421918 9.9366057,78.1421918 9.9367106,78.1419488
我有一个table这样的
aa<-tribble(
~"a",~"b",~"c",~"d",
" 78.1445111, 9.9365072", "78.1444646, 9.9365044", " 78.1445111, 9.9365072", "78.1444646, 9.9365044",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
)
这些是“纬度、经度”值。我想将它们转换成“long, lat”。例如,我想将“78.1445111, 9.9365072”转换为“9.9365072,78.1445111”。在 r 中是否可以对所有列进行自动化?
我希望在所有列中都有这样的输出:
a<- tribble(
~"a",~"b",~"c",~"d",
"9.9365072,78.1445111", "9.9365044,78.1444646,", "9.9365072,78.1445111", "9.9365044,78.1444646,",
"9.9365166,78.1444197", "9.9365422,78.1443816",
"9.9365748,78.142359", "9.9366057,78.1421918",
"9.9366057,78.1421918", "9.9367106,78.1419488",
"9.9365166,78.1444197", "9.9365422,78.1443816",
"9.9365748,78.142359", "9.9366057,78.1421918",
"9.9366057,78.1421918", "9.9367106,78.1419488"
)
我试过但失败了:
bag_1<-list()
for(i in colnames(a)){
dummy <-str_split_fixed(a[[i]], ",", 2)
bag_1[[i]]<-dummy
dum<-do.call(rbind,bag_1)
}
这样可以吗?使用 dplyr
和 tidyr
函数
library(tidyverse)
aa %>% mutate(id = row_number()) %>%
pivot_longer(cols = -id) %>%
separate(value, into = c("Lat", "Long"), sep = ", ") %>%
mutate(new = paste(Long, Lat, sep = ", ")) %>%
select(-Lat, -Long) %>%
pivot_wider(id_cols = id, names_from = name, values_from = new)
# A tibble: 4 x 5
id a b c d
<int> <chr> <chr> <chr> <chr>
1 1 9.9365072, 78.1445111 9.9365044, 78.1444646 9.9365072, 78.1445111 9.9365044, 78.1444646
2 2 9.9365166, 78.1444197 9.9365422, 78.1443816 9.9365748, 78.142359 9.9366057, 78.1421918
3 3 9.9366057, 78.1421918 9.9367106, 78.1419488 9.9365166, 78.1444197 9.9365422, 78.1443816
4 4 9.9365748, 78.142359 9.9366057, 78.1421918 9.9366057, 78.1421918 9.9367106, 78.1419488
aa
使用
aa <- tribble(
~"a",~"b",~"c",~"d",
"78.1445111, 9.9365072", "78.1444646, 9.9365044", "78.1445111, 9.9365072", "78.1444646, 9.9365044",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
)
在 Base R
中,您可以颠倒每列 strsplit()
字符向量的顺序:
sapply(aa, function(x){
# first strsplit
tmp1 <- strsplit(x, ", ", fixed = T)
# reverse and paste
sapply(tmp1, function(z){
paste(rev(z), collapse = ", ")
})
})
# yields
# a b c d
# [1,] "9.9365072, 78.1445111" "9.9365044, 78.1444646" "9.9365072, 78.1445111" "9.9365044, 78.1444646"
# [2,] "9.9365166, 78.1444197" "9.9365422, 78.1443816" "9.9365748, 78.142359" "9.9366057, 78.1421918"
# [3,] "9.9366057, 78.1421918" "9.9367106, 78.1419488" "9.9365166, 78.1444197" "9.9365422, 78.1443816"
# [4,] "9.9365748, 78.142359" "9.9366057, 78.1421918" "9.9366057, 78.1421918" "9.9367106, 78.1419488"
你可以用 dplyr::mutate 和 stringr::str_replace:
# across all column
aa %>% mutate(across(everything(),
# capture the non-comma characters into 2 groups
~ str_replace((.),"([^,]+),([^,]+)",
# switch first and second capture groups around
"\2,\1")))
基础 R 选项:
编写一个函数来反转字符串:
reverse_string <- function(x) {
trimws(paste(sub('.*,', '', x), sub(',.*', '', x), sep = ','))
}
使用 lapply
对每一列应用它。
aa[] <- lapply(aa, reverse_string)
aa
# A tibble: 4 x 4
# a b c d
# <chr> <chr> <chr> <chr>
#1 9.9365072, 78.1445111 9.9365044,78.1444646 9.9365072, 78.1445111 9.9365044,78.1444646
#2 9.9365166,78.1444197 9.9365422,78.1443816 9.9365748,78.142359 9.9366057,78.1421918
#3 9.9366057,78.1421918 9.9367106,78.1419488 9.9365166,78.1444197 9.9365422,78.1443816
#4 9.9365748,78.142359 9.9366057,78.1421918 9.9366057,78.1421918 9.9367106,78.1419488