R 程序:具有非唯一 ID 的数据框。需要创建具有唯一 ID 的列
R Program: Have dataframe with non-unique IDs. Need to create column with unique IDs
我有一个数据框,其中包含具有唯一值的重复 ID。我需要使 ID 唯一。
df <- read.csv("test.csv")
ID: A1, A1, A2, A2, A3, A3, A4, A4
Value: 0.5, 0.9, 1.5, 0.8, 2.2, 2.4, 3.1, 0.5
我需要获取这个数据框:
ID: A1_1, A1_2, A2_1, A2_2, A3_1, A3_2, A4_1, A4_2
Value: 0.5, 0.9, 1.5, 0.8, 2.2, 2.4, 3.1, 0.5
我尝试了以下代码,它添加了一个重复交替的 _1 和 _2 的列,并连接到 ID:
unique <- c("_1", "_2")
Unique.col <- matrix(rep(unique, ))
unique_ID <- cbind(df, Unique.col)
unique_ID$ID <- paste(unique_ID$ID, unique_ID$Unique.col)
unique_ID
我得到以下数据框,其中 A1 和 _1 之间有一个 space:
ID: A1 _1, A1 _2, A2 _1, A2 _2, A3 _1, A3 _2, A4 _1, A4 _2
Value: 0.5, 0.9, 1.5, 0.8, 2.2, 2.4, 3.1, 0.5
是否有更好的方法或摆脱 space 的方法?
您可以使用gsub(" ","",unique_ID)
删除空格
示例:
unique_ID <- c("A1 _1", "A1 _2", "A2 _1", "A2 _2", "A3 _1", "A3 _2", "A4 _1",
"A4 _2")
test <- gsub(" ","",unique_ID)
> test
[1] "A1_1" "A1_2" "A2_1" "A2_2" "A3_1" "A3_2" "A4_1"
[8] "A4_2"
解决此问题的一般 dplyr
/tidyr
方法是同时利用 pivot_longer
和 pivot_wider
:加长,然后按原始列名分组并创建唯一的组内 ID,然后加宽。这似乎有点偏离通常的旋转精神,但它完成了工作!
示例数据:
df <- tribble(
~"A1", ~"A1", ~"A2", ~"A2", ~"A3", ~"A3", ~"A4", ~"A4",
1, 2, 3, 4, 5, 6, 7, 8
)
要创建唯一的组内 ID,请参阅 this answer. For combining those IDs with the original column names, the tidyr
pivoting vignette has some great examples (e.g. here)。关键是使用 names_from
参数将原始列名称与新 ID 结合起来。这让我们:
df %>%
# Pivot original column names to "name" column and original values to "value" column
pivot_longer(cols=everything()) %>%
# Create unique IDs within each original column
group_by(name) %>%
mutate(row_id=row_number()) %>%
# Pivot back to the desired wider format
pivot_wider(names_from=c(name, row_id))
输出:
# A tibble: 1 x 8
A1_1 A1_2 A2_1 A2_2 A3_1 A3_2 A4_1 A4_2
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 3 4 5 6 7 8
我们还可以在对 pivot_wider
的调用中更改新列名称的格式,使用 names_sep
(默认为 _
)或使用 names_pattern
(它采用正则表达式)。
我有一个数据框,其中包含具有唯一值的重复 ID。我需要使 ID 唯一。
df <- read.csv("test.csv")
ID: A1, A1, A2, A2, A3, A3, A4, A4
Value: 0.5, 0.9, 1.5, 0.8, 2.2, 2.4, 3.1, 0.5
我需要获取这个数据框:
ID: A1_1, A1_2, A2_1, A2_2, A3_1, A3_2, A4_1, A4_2
Value: 0.5, 0.9, 1.5, 0.8, 2.2, 2.4, 3.1, 0.5
我尝试了以下代码,它添加了一个重复交替的 _1 和 _2 的列,并连接到 ID:
unique <- c("_1", "_2")
Unique.col <- matrix(rep(unique, ))
unique_ID <- cbind(df, Unique.col)
unique_ID$ID <- paste(unique_ID$ID, unique_ID$Unique.col)
unique_ID
我得到以下数据框,其中 A1 和 _1 之间有一个 space:
ID: A1 _1, A1 _2, A2 _1, A2 _2, A3 _1, A3 _2, A4 _1, A4 _2
Value: 0.5, 0.9, 1.5, 0.8, 2.2, 2.4, 3.1, 0.5
是否有更好的方法或摆脱 space 的方法?
您可以使用gsub(" ","",unique_ID)
删除空格
示例:
unique_ID <- c("A1 _1", "A1 _2", "A2 _1", "A2 _2", "A3 _1", "A3 _2", "A4 _1",
"A4 _2")
test <- gsub(" ","",unique_ID)
> test
[1] "A1_1" "A1_2" "A2_1" "A2_2" "A3_1" "A3_2" "A4_1"
[8] "A4_2"
解决此问题的一般 dplyr
/tidyr
方法是同时利用 pivot_longer
和 pivot_wider
:加长,然后按原始列名分组并创建唯一的组内 ID,然后加宽。这似乎有点偏离通常的旋转精神,但它完成了工作!
示例数据:
df <- tribble(
~"A1", ~"A1", ~"A2", ~"A2", ~"A3", ~"A3", ~"A4", ~"A4",
1, 2, 3, 4, 5, 6, 7, 8
)
要创建唯一的组内 ID,请参阅 this answer. For combining those IDs with the original column names, the tidyr
pivoting vignette has some great examples (e.g. here)。关键是使用 names_from
参数将原始列名称与新 ID 结合起来。这让我们:
df %>%
# Pivot original column names to "name" column and original values to "value" column
pivot_longer(cols=everything()) %>%
# Create unique IDs within each original column
group_by(name) %>%
mutate(row_id=row_number()) %>%
# Pivot back to the desired wider format
pivot_wider(names_from=c(name, row_id))
输出:
# A tibble: 1 x 8
A1_1 A1_2 A2_1 A2_2 A3_1 A3_2 A4_1 A4_2
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 3 4 5 6 7 8
我们还可以在对 pivot_wider
的调用中更改新列名称的格式,使用 names_sep
(默认为 _
)或使用 names_pattern
(它采用正则表达式)。