重新格式化输入数据

时间:2018-07-18 16:18:11

标签: r

我有一个包含两列(边缘文件)的数据,它们代表顶点ID,并且连接为

v1,v2

23732,23778

23732,23871

23732,58098

23778,23824

23778,23871

23778,58098

23871,58009

23871,58098

58009,58098

58098,58256

我需要重新格式化它,即顶点ID必须是连续的,并以这样的一个开头

v1,v2

1,2

1,3

1,4

2,5

2,3

2,4

3,5

3,4

5,4

4,6

有人可以建议如何自动执行吗? 另外,我需要同时具有原始ID和新ID的转换表。 感谢您的支持。

2 个答案:

答案 0 :(得分:1)

这是另一种使用factor()进行重新编号的方法:

library(data.table)
# reshape from wide to long format using row  numbers
tmp <- melt(setDT(DT)[, rn := .I], "rn", value.name = "old")[
  # create new ids from factor levels
  , new := as.integer(factor(old))][]

# reshape back to wide format again
dcast(tmp, rn ~ variable, value.var = "new")[, -"rn"]
    v1 v2
 1:  1  2
 2:  1  4
 3:  1  6
 4:  2  3
 5:  2  4
 6:  2  6
 7:  4  5
 8:  4  6
 9:  5  6
10:  6  7

可以通过以下方式创建翻译表

tmp[, unique(.SD), .SDcols = c("old", "new")]
     old new
1: 23732   1
2: 23778   2
3: 23871   4
4: 58009   5
5: 58098   6
6: 23824   3
7: 58256   7

为了精确地再现 OP的新编号,我们需要使用fct_inorder()包中的forcats函数重新排列因子水平:

tmp <- melt(DT[, rn := .I], "rn", value.name = "old")[
  order(rn, variable), new := as.integer(forcats::fct_inorder(factor(old)))][]
dcast(tmp, rn ~ variable, value.var = "new")[, -"rn"]
    v1 v2
 1:  1  2
 2:  1  3
 3:  1  4
 4:  2  5
 5:  2  3
 6:  2  4
 7:  3  6
 8:  3  4
 9:  6  4
10:  4  7

然后,翻译变成

     old new
1: 23732   1
2: 23778   2
3: 23871   3
4: 58009   6
5: 58098   4
6: 23824   5
7: 58256   7

数据

library(data.table)
DT <- fread(
  "v1,v2
23732,23778
23732,23871
23732,58098
23778,23824
23778,23871
23778,58098
23871,58009
23871,58098
58009,58098
58098,58256"
)

答案 1 :(得分:0)

这不是您真正想要的,因为我在分配ID之前对节点名称进行了排序。

我选择做的是获取所有唯一的节点ID,对它们进行排序,然后将每个ID分配给一个整数。

df <- structure(list(v1 = c(23732L, 23732L, 23732L, 23778L, 23778L, 
    23778L, 23871L, 23871L, 58009L, 58098L), v2 = c(23778L, 23871L, 
    58098L, 23824L, 23871L, 58098L, 58009L, 58098L, 58098L, 58256L
    )), .Names = c("v1", "v2"), class = "data.frame", row.names = c(NA, 
    -10L))

# Put nodes in ascending order
df <- df[order(df$v1, df$v2), ]

# create a mapping of node number to node ID (as a vector)
# All unique nodes between the two columns, sorted
node_names <- sort(unique(c(df$v1, df$v2)))
# a vector of integers from 1 to length(node_names)
node_id <- seq_along(node_names)
# assign (map) the node names to the integer values
names(node_id) <- node_names

# Add the node IDs to df
df$v1_id <- node_id[as.character(df$v1)]
df$v2_id <- node_id[as.character(df$v2)]
df

      v1    v2 v1_id v2_id
1  23732 23778     1     2
2  23732 23871     1     4
3  23732 58098     1     6
4  23778 23824     2     3
5  23778 23871     2     4
6  23778 58098     2     6
7  23871 58009     4     5
8  23871 58098     4     6
9  58009 58098     5     6
10 58098 58256     6     7