是否有一个 R 函数可以按照它在数据集中出现的顺序依次为数据框中的每个值分配一个代码?
Is there an R function to sequentially assign a code to each value in a dataframe, in the order it appears within the dataset?
我有一个 table,其中包含一长串像这样的别名值:
> 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
提前感谢您的帮助!
你可以这样做:
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
您可以 match
针对唯一值。对于单个向量,代码很简单:
match(vec, unique(vec))
在行之前遍历列的要求使这有点棘手:您需要先转置值。在那之后,match
他们。
最后,使用 [<-
将结果分配回与原始数据(此处 x
)相同形状的 data.frame:
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(…)
丢弃属性。特别是,它降低了转置矩阵的维度,即将矩阵转换为向量,现在值的顺序正确。
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
我有一个 table,其中包含一长串像这样的别名值:
> 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
提前感谢您的帮助!
你可以这样做:
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
您可以 match
针对唯一值。对于单个向量,代码很简单:
match(vec, unique(vec))
在行之前遍历列的要求使这有点棘手:您需要先转置值。在那之后,match
他们。
最后,使用 [<-
将结果分配回与原始数据(此处 x
)相同形状的 data.frame:
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(…)
丢弃属性。特别是,它降低了转置矩阵的维度,即将矩阵转换为向量,现在值的顺序正确。
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