R语言 对多列中的值进行排序并创建新变量

bpzcxfmw  于 2023-04-03  发布在  其他
关注(0)|答案(4)|浏览(142)

我有一个 Dataframe ,看起来像这样:

CityFrom         CityTo   Count
     Paris           Lyon       2
      Lyon          Paris       4
    London     Manchester       5
Manchester         London       6

我想在每一行中添加2个额外的列,这将为我提供一个城市名称,无论目的地和起点如何排序:

所以,作为一个例子,里昂-巴黎和巴黎-里昂在这种情况下是相同的。
我最初的想法是:
1.使用paste合并2列,即CityFrom和CityTo

  1. sort按字母顺序排列
  2. split它们在2列中。
    作为一个用例,巴黎作为CityFrom,里昂作为CityTo的行:
  3. paste 2列给予-“巴黎,里昂”。
  4. sort给予输出-“里昂,巴黎”
  5. split分为2列,其中里昂为CityCodeBidirectionalFrom,巴黎为CityCodeBidirectionalto。
    我无法实现上述逻辑。
cclgggtu

cclgggtu1#

实际上你不需要“排序”,只需要比较每一对。你需要做两次,翻转条件从一对中得到另一个:

library(tidyverse)

d %>% 
  mutate(
    CityCodeBidirectionalFrom = if_else(CityFrom < CityTo, CityFrom, CityTo),
    CityCodeBidirectionalTo = if_else(CityFrom > CityTo, CityFrom, CityTo))

(as你没有提供任何测试数据,我的代码是一个未经测试的伪代码,而不是一个复制粘贴解决方案…)

gk7wooem

gk7wooem2#

另一个选项是使用pmin()pmax()

cbind(df, sapply(c(CityCodeBidirectionalFrom = pmin,
                   CityCodeBidirectionalTo = pmax), do.call, df[1:2]))

    CityFrom     CityTo Count CityCodeBidirectionalFrom CityCodeBidirectionalTo
1      Paris       Lyon     2                      Lyon                   Paris
2       Lyon      Paris     4                      Lyon                   Paris
3     London Manchester     5                    London              Manchester
4 Manchester     London     6                    London              Manchester
fkvaft9z

fkvaft9z3#

对于tidyverse解决方案,我们可以将它们放入一个列表中,对其进行排序,然后将它们解嵌套。

library(dplyr)
library(tidyr)
library(purrr)

df1 %>% 
  mutate(CityCodeBidirectional = map2(CityFrom, CityTo, ~sort(c(.x , .y)))) %>% 
  unnest_wider(data = ., col = CityCodeBidirectional, 
                         names_sep = c("From", "To"), names_repair = "universal")

#> # A tibble: 4 x 5
#>   CityFrom   CityTo     Count CityCodeBidirectionalF~ CityCodeBidirectiona~
#>   <chr>      <chr>      <int> <chr>                   <chr>                
#> 1 Paris      Lyon           2 Lyon                    Paris                
#> 2 Lyon       Paris          4 Lyon                    Paris                
#> 3 London     Manchester     5 London                  Manchester           
#> 4 Manchester London         6 London                  Manchester

数据:

df1 <- read.table(text="CityFrom    CityTo  Count
                        Paris   Lyon    2
                        Lyon    Paris   4
                        London  Manchester  5
                        Manchester London       6",
                  header = T, stringsAsFactors = F)
6fe3ivhb

6fe3ivhb4#

您可以对值进行排序,而不需要连接,如下所示:

df = data.frame(
    CityFrom = c("Paris", "Lyon", "London", "Manchester"),
    CityTo = c("Lyon", "Paris", "Manchester", "London"),
    Count = c(2, 4, 5, 6),
    stringsAsFactors = FALSE
)

mysort = apply(df[,1:2], 1, sort)
rownames(mysort) = c("CityCodeBidirectionalFrom", "CityCodeBidirectionalTo")
cbind(df, t(mysort), stringsAsFactors=FALSE)
##     CityFrom     CityTo Count CityCodeBidirectionalFrom CityCodeBidirectionalTo
## 1      Paris       Lyon     2                      Lyon                   Paris
## 2       Lyon      Paris     4                      Lyon                   Paris
## 3     London Manchester     5                    London              Manchester
## 4 Manchester     London     6                    London              Manchester

相关问题