R 中的 rbind 数据帧,可以向重复的行名添加多个数字吗?
rbind data frames in R, possible to add more than a number to duplicated rownames?
在 R 中使用 rbind 合并两个具有相同行名的数据框时,它会将“1”添加到第二行名。
df1 = data.frame(A=1:3,B=1:3)
df2 = data.frame(A=1:3,B=1:3)
rownames(df1) = c("A1","B1","C1")
rownames(df2) = c("C1","C2","C3")
rbind(df1,df2)
# A B
# A1 1 1
# B1 2 2
# C1 3 3
# C11 1 1
# C2 2 2
# C3 3 3
但是,在我的例子中,行名称已经包含带有数字的字母(基因名称),因此添加一个额外的“1”将 C 从数字 1 更改为数字 11。有没有办法强制 rbind 例如添加额外的点或下划线,使“C1”变为“C1.1”或“C1_1”而不是“C11”?
您可以将重要信息放在单独的列中,而不是将它们存储在行名中。使用 make.unique
获得唯一的名称。
library(dplyr)
library(tibble)
res <- df1 %>%
rownames_to_column() %>%
bind_rows(df2 %>% rownames_to_column()) %>%
mutate(rowname = make.unique(rowname, sep = '_'))
res
# rowname A B
#1 A1 1 1
#2 B1 2 2
#3 C1 3 3
#4 C1_1 1 1
#5 C2 2 2
#6 C3 3 3
如果您需要返回值作为行名,请使用 column_to_rownames
。
res %>% column_to_rownames()
# A B
#A1 1 1
#B1 2 2
#C1 3 3
#C1_1 1 1
#C2 2 2
#C3 3 3
改编自,之后您可以创建新的行名:
df1 = data.frame(A=1:3,B=1:3)
df2 = data.frame(A=1:3,B=1:3)
rownames(df1) = c("A1","B1","C1")
rownames(df2) = c("C1","C2","C3")
new_df <- rbind(df1,df2)
# create new row names
rownames(new_df) <- c(paste0(rownames(df1), "_df1"), paste0(rownames(df2), "_df2"))
输出:
> print(new_df)
A B
A1_df1 1 1
B1_df1 2 2
C1_df1 3 3
C1_df2 1 1
C2_df2 2 2
C3_df2 3 3
您可以使用 make.names()
对其进行改进,此功能会检查每个名称是否唯一以及是否不包含“禁止”字符。
make.names(c(paste0(rownames(df1), "_df1"), paste0(rownames(df2), "_df2")), unique = TRUE)
一种data.table
方法
library(data.table)
# make list of df's
L <- list(df1, df2)
# set to data.tables, keep rownames in column 'rn'
L <- lapply(L, setDT, keep.rownames = TRUE)
# rowbind to data.table
DT <- rbindlist(L, use.names = TRUE)
# temparary value id
DT[, id := rowid(rn)]
#create new rd, remove temporary column
DT[id > 1, rn := paste(rn, id - 1, sep = ".")][, id := NULL]
# rn A B
# 1: A1 1 1
# 2: B1 2 2
# 3: C1 3 3
# 4: C1.1 1 1
# 5: C2 2 2
# 6: C3 3 3
在 R 中使用 rbind 合并两个具有相同行名的数据框时,它会将“1”添加到第二行名。
df1 = data.frame(A=1:3,B=1:3)
df2 = data.frame(A=1:3,B=1:3)
rownames(df1) = c("A1","B1","C1")
rownames(df2) = c("C1","C2","C3")
rbind(df1,df2)
# A B
# A1 1 1
# B1 2 2
# C1 3 3
# C11 1 1
# C2 2 2
# C3 3 3
但是,在我的例子中,行名称已经包含带有数字的字母(基因名称),因此添加一个额外的“1”将 C 从数字 1 更改为数字 11。有没有办法强制 rbind 例如添加额外的点或下划线,使“C1”变为“C1.1”或“C1_1”而不是“C11”?
您可以将重要信息放在单独的列中,而不是将它们存储在行名中。使用 make.unique
获得唯一的名称。
library(dplyr)
library(tibble)
res <- df1 %>%
rownames_to_column() %>%
bind_rows(df2 %>% rownames_to_column()) %>%
mutate(rowname = make.unique(rowname, sep = '_'))
res
# rowname A B
#1 A1 1 1
#2 B1 2 2
#3 C1 3 3
#4 C1_1 1 1
#5 C2 2 2
#6 C3 3 3
如果您需要返回值作为行名,请使用 column_to_rownames
。
res %>% column_to_rownames()
# A B
#A1 1 1
#B1 2 2
#C1 3 3
#C1_1 1 1
#C2 2 2
#C3 3 3
改编自
df1 = data.frame(A=1:3,B=1:3)
df2 = data.frame(A=1:3,B=1:3)
rownames(df1) = c("A1","B1","C1")
rownames(df2) = c("C1","C2","C3")
new_df <- rbind(df1,df2)
# create new row names
rownames(new_df) <- c(paste0(rownames(df1), "_df1"), paste0(rownames(df2), "_df2"))
输出:
> print(new_df)
A B
A1_df1 1 1
B1_df1 2 2
C1_df1 3 3
C1_df2 1 1
C2_df2 2 2
C3_df2 3 3
您可以使用 make.names()
对其进行改进,此功能会检查每个名称是否唯一以及是否不包含“禁止”字符。
make.names(c(paste0(rownames(df1), "_df1"), paste0(rownames(df2), "_df2")), unique = TRUE)
一种data.table
方法
library(data.table)
# make list of df's
L <- list(df1, df2)
# set to data.tables, keep rownames in column 'rn'
L <- lapply(L, setDT, keep.rownames = TRUE)
# rowbind to data.table
DT <- rbindlist(L, use.names = TRUE)
# temparary value id
DT[, id := rowid(rn)]
#create new rd, remove temporary column
DT[id > 1, rn := paste(rn, id - 1, sep = ".")][, id := NULL]
# rn A B
# 1: A1 1 1
# 2: B1 2 2
# 3: C1 3 3
# 4: C1.1 1 1
# 5: C2 2 2
# 6: C3 3 3