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_longerpivot_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(它采用正则表达式)。