5

我有一个包含一长串别名值的表,如下所示:

> head(transmission9, 50)
# A tibble: 50 x 2
   In_Node  End_Node
   <chr>    <chr>   
 1 c4ca4238 2838023a
 2 c4ca4238 d82c8d16
 3 c4ca4238 a684ecee
 4 c4ca4238 fc490ca4
 5 28dd2c79 c4ca4238
 6 f899139d 3def184a

我想让 R 遍历两列并按顺序为每个值分配一个数字,按照别名值出现在数据集中的顺序。我希望 R 先跨行读取,然后向下读取列。例如,对于上面的数据集:

   In_Node  End_Node
   <chr>    <chr>   
 1  1       2
 2  1       3
 3  1       4
 4  1       5
 5  6       1
 6  7       8

这可能吗?理想情况下,我也希望能够生成一个“密钥”,它将每个顺序代码与每个别名值匹配,如下所示:

Code Value
1    c4ca4238
2    2838023a
3    d82c8d16
4    a684ecee
5    fc490ca4

提前感谢您的帮助!

4

3 回答 3

5

你可以match反对独特的价值观。对于单个向量,代码很简单:

match(vec, unique(vec))

在行之前遍历列的要求使这有点棘手:您需要先转置值。之后,match他们。

最后,用于[<-将结果分配回与原始数据形状相同的 data.frame(此处x):

y = x
y[] = match(unlist(x), unique(c(t(x))))
y
  V2 V3
1  1  2
2  1  3
3  1  4
4  1  5
5  6  1
6  7  8

c(t(x))有点小技巧:

  • t首先将 tibble 转换为矩阵,然后将其转置。如果您的 tibble 包含多种数据类型,这些数据类型将被强制转换为通用类型。
  • c(…)丢弃属性。特别是,它丢弃了转置矩阵的维度,即将矩阵转换为向量,现在的值顺序正确。
于 2021-07-15T15:52:06.933 回答
5

你可以这样做:

df1 <- df
df1[]<-as.numeric(factor(unlist(df), unique(c(t(df)))))
df1
  In_Node End_Node
1       1        2
2       1        3
3       1        4
4       1        5
5       6        1
6       7        8
于 2021-07-15T15:50:34.773 回答
4

一个 dplyr 版本

library(tidyverse)

transmission9 <- read.table(header = T, text = "   In_Node  End_Node
 1 c4ca4238 283802d3a
 2 c4ca4238 d82c8d16
 3 c4ca4238 a684ecee
 4 c4ca4238 fc490ca4
 5 28dd2c79 c4ca4238
 6 f899139d 3def184a")

transmission9 %>% 
  mutate(across(everything(), ~ match(., unique(c(t(cur_data()))))))
#>   In_Node End_Node
#> 1       1        2
#> 2       1        3
#> 3       1        4
#> 4       1        5
#> 5       6        1
#> 6       7        8

.names如果要创建新列,请使用参数

transmission9 %>% 
  mutate(across(everything(), ~ match(., unique(c(t(cur_data())))),
                .names = '{.col}_code'))

   In_Node End_Node In_Node_code End_Node_code
1 c4ca4238 2838023a            1             2
2 c4ca4238 d82c8d16            1             3
3 c4ca4238 a684ecee            1             4
4 c4ca4238 fc490ca4            1             5
5 28dd2c79 c4ca4238            6             1
6 f899139d 3def184a            7             8
于 2021-07-15T16:02:35.223 回答