根据 R 中另一列中的唯一值创建升序值列,并批量添加新数据
Create column of ascending values based on unique values in another column in R with new data added in batches
我在 Python () 中问过类似的问题,并使脚本正常工作,但出于各种原因,我现在需要在 R 中实现相同的功能。我在这里还增加了复杂性,希望能够定期向数据集添加新批次的数据。
我有一个样本列表,这些样本具有唯一的样本 ID 号 ("Sample_ID")。数据集的每一行都是一个样本。一些样品被重复多次。我想创建一组新的示例名称 ("Sample_code"),当您使用前缀(例如 "SAMP00001"、"SAMP00002" 等)沿着行向下时,它会从 1 上升。我希望保留行的顺序(因为它们大致按照样本收集的日期顺序)。对于重复的样本,我希望为 Sample_code 给出的数字对应于样本 ID 出现的第一行,而不是 table 后面的行(稍后出现在样本集合中)。
我的起始数据用df1说明:
# df1
Sample_ID <- c('123123','123456','123123','123789')
Date <- c('15/06/2019', '23/06/2019', '30/06/2019', '07/07/2019')
Variable <- c("blue","red","red","blue")
Batch <- 1
df1 <- data.frame(Sample_ID, Date, Variable, Batch)
df1
我想创建 df1b 中显示的 Sample_code 列:
# df1b
Sample_ID <- c('123123','123456','123123','123789')
Date <- c('15/06/2019', '23/06/2019', '30/06/2019', '07/07/2019')
Variable <- c("blue","red","red","blue")
Batch <- 1
Sample_code <- c('SAMP0001', 'SAMP0002', 'SAMP0001', 'SAMP0003')
df1b <- data.frame(Sample_ID, Date, Variable, Batch, Sample_code)
df1b
此时我将保存 df1b 以及那些用于下游处理的 Sample_code 名称。增加的复杂性是因为我将收集一批新的样本——我们称之为 df2(第 2 批样本):
# df2
Sample_ID <- c('456789', '123654', '123123', '123789', '121212')
Date <- c('15/07/2019', '31/07/2019', '12/08/2019', '27/08/2019', '31/08/2019')
Variable <- c("blue", "red","blue", "red", "red")
Batch <- 2
df2 <- data.frame(Sample_ID, Date, Variable, Batch)
df2
我想将 df2 绑定到 df1 的底部,并为新行生成更多 Sample_code 名称。重要的是,新的 Sample_code 名称需要考虑 df1 中存在的任何 Sample_ID 重复名称,但也不要更改任何 Sample_code 名称,这些名称在我只有df1。此时的结果将是 df2b,如下:
# df2b
Sample_ID <- c('123123','123456','123123','123789','456789', '123654', '123123', '123789', '121212')
Date <- c('15/06/2019', '23/06/2019', '30/06/2019', '07/07/2019', '15/07/2019', '31/07/2019', '12/08/2019', '27/08/2019', '31/08/2019')
Variable <- c("blue","red","red","blue","blue", "red","blue", "red", "red")
Batch <- c(1,1,1,1,2,2,2,2,2)
Sample_code <- c('SAMP0001', 'SAMP0002', 'SAMP0001', 'SAMP0003', 'SAMP0004', 'SAMP0005', 'SAMP0001', 'SAMP0003', 'SAMP0006')
df2b <- data.frame(Sample_ID, Date, Variable, Batch, Sample_code)
df2b
然后我会以同样的方式添加第 3 批样本等等
我知道这个问题至少有两个阶段:1) 使用唯一的 Sample_ID 值生成 Sample_code 名称的升序列表; 2) 以迭代方式添加样本批次进行构建。但是因为第二点会影响我想要的 Sample_code 名称的功能,所以我在此处包含了两个阶段。
最后 - 理想情况下我只想为此使用基础 R 和 tidyverse 包。
非常感谢任何帮助!谢谢。
因为您需要在示例代码分配之前知道所有可能的示例 ID,请考虑通过在所有示例数据帧上调用 rbind
来颠倒顺序。然后使用 factor
级别分配 Sample_code。否则,为每个批处理数据帧重新分配 Sample_code。
# BUILD A LIST OF DATA FRAMES BY CALLING lapply ON ITERATIVE PROCESS
# df_list <- lapply(batch_iterable, method_to_build_sample)
df_list <- list(df1, df1b, df2) # FOR THIS PARTICULAR POST
# RBIND ALL DFs TOGETHER
df2b <- do.call(rbind, df_list)
df2b <- within(df2b, {
# CONVERT TO CHARACTER
Sample_ID <- as.character(Sample_ID)
# CONVERT TO FACTOR AT POSITIONED VALUES, THEN INTEGER FOR LEVEL NUMBER
Sample_code <- as.character(as.integer(factor(Sample_ID, levels = unique(Sample_ID))))
# RE-ASSIGN WITH SAMP AND LEADING ZEROS
Sample_code <- ifelse(nchar(Sample_code) == 1, paste0('SAMP000', Sample_code),
ifelse(nchar(Sample_code) == 2, paste0('SAMP00', Sample_code),
ifelse(nchar(Sample_code) == 3, paste0('SAMP0', Sample_code), NA)
)
)
})
df2b
# Sample_ID Date Variable Batch Sample_code
# 1 123123 15/06/2019 blue 1 SAMP0001
# 2 123456 23/06/2019 red 1 SAMP0002
# 3 123123 30/06/2019 red 1 SAMP0001
# 4 123789 07/07/2019 blue 1 SAMP0003
# 5 456789 15/07/2019 blue 2 SAMP0004
# 6 123654 31/07/2019 red 2 SAMP0005
# 7 123123 12/08/2019 blue 2 SAMP0001
# 8 123789 27/08/2019 red 2 SAMP0003
# 9 121212 31/08/2019 red 2 SAMP0006
我在 Python (
我有一个样本列表,这些样本具有唯一的样本 ID 号 ("Sample_ID")。数据集的每一行都是一个样本。一些样品被重复多次。我想创建一组新的示例名称 ("Sample_code"),当您使用前缀(例如 "SAMP00001"、"SAMP00002" 等)沿着行向下时,它会从 1 上升。我希望保留行的顺序(因为它们大致按照样本收集的日期顺序)。对于重复的样本,我希望为 Sample_code 给出的数字对应于样本 ID 出现的第一行,而不是 table 后面的行(稍后出现在样本集合中)。
我的起始数据用df1说明:
# df1
Sample_ID <- c('123123','123456','123123','123789')
Date <- c('15/06/2019', '23/06/2019', '30/06/2019', '07/07/2019')
Variable <- c("blue","red","red","blue")
Batch <- 1
df1 <- data.frame(Sample_ID, Date, Variable, Batch)
df1
我想创建 df1b 中显示的 Sample_code 列:
# df1b
Sample_ID <- c('123123','123456','123123','123789')
Date <- c('15/06/2019', '23/06/2019', '30/06/2019', '07/07/2019')
Variable <- c("blue","red","red","blue")
Batch <- 1
Sample_code <- c('SAMP0001', 'SAMP0002', 'SAMP0001', 'SAMP0003')
df1b <- data.frame(Sample_ID, Date, Variable, Batch, Sample_code)
df1b
此时我将保存 df1b 以及那些用于下游处理的 Sample_code 名称。增加的复杂性是因为我将收集一批新的样本——我们称之为 df2(第 2 批样本):
# df2
Sample_ID <- c('456789', '123654', '123123', '123789', '121212')
Date <- c('15/07/2019', '31/07/2019', '12/08/2019', '27/08/2019', '31/08/2019')
Variable <- c("blue", "red","blue", "red", "red")
Batch <- 2
df2 <- data.frame(Sample_ID, Date, Variable, Batch)
df2
我想将 df2 绑定到 df1 的底部,并为新行生成更多 Sample_code 名称。重要的是,新的 Sample_code 名称需要考虑 df1 中存在的任何 Sample_ID 重复名称,但也不要更改任何 Sample_code 名称,这些名称在我只有df1。此时的结果将是 df2b,如下:
# df2b
Sample_ID <- c('123123','123456','123123','123789','456789', '123654', '123123', '123789', '121212')
Date <- c('15/06/2019', '23/06/2019', '30/06/2019', '07/07/2019', '15/07/2019', '31/07/2019', '12/08/2019', '27/08/2019', '31/08/2019')
Variable <- c("blue","red","red","blue","blue", "red","blue", "red", "red")
Batch <- c(1,1,1,1,2,2,2,2,2)
Sample_code <- c('SAMP0001', 'SAMP0002', 'SAMP0001', 'SAMP0003', 'SAMP0004', 'SAMP0005', 'SAMP0001', 'SAMP0003', 'SAMP0006')
df2b <- data.frame(Sample_ID, Date, Variable, Batch, Sample_code)
df2b
然后我会以同样的方式添加第 3 批样本等等
我知道这个问题至少有两个阶段:1) 使用唯一的 Sample_ID 值生成 Sample_code 名称的升序列表; 2) 以迭代方式添加样本批次进行构建。但是因为第二点会影响我想要的 Sample_code 名称的功能,所以我在此处包含了两个阶段。
最后 - 理想情况下我只想为此使用基础 R 和 tidyverse 包。
非常感谢任何帮助!谢谢。
因为您需要在示例代码分配之前知道所有可能的示例 ID,请考虑通过在所有示例数据帧上调用 rbind
来颠倒顺序。然后使用 factor
级别分配 Sample_code。否则,为每个批处理数据帧重新分配 Sample_code。
# BUILD A LIST OF DATA FRAMES BY CALLING lapply ON ITERATIVE PROCESS
# df_list <- lapply(batch_iterable, method_to_build_sample)
df_list <- list(df1, df1b, df2) # FOR THIS PARTICULAR POST
# RBIND ALL DFs TOGETHER
df2b <- do.call(rbind, df_list)
df2b <- within(df2b, {
# CONVERT TO CHARACTER
Sample_ID <- as.character(Sample_ID)
# CONVERT TO FACTOR AT POSITIONED VALUES, THEN INTEGER FOR LEVEL NUMBER
Sample_code <- as.character(as.integer(factor(Sample_ID, levels = unique(Sample_ID))))
# RE-ASSIGN WITH SAMP AND LEADING ZEROS
Sample_code <- ifelse(nchar(Sample_code) == 1, paste0('SAMP000', Sample_code),
ifelse(nchar(Sample_code) == 2, paste0('SAMP00', Sample_code),
ifelse(nchar(Sample_code) == 3, paste0('SAMP0', Sample_code), NA)
)
)
})
df2b
# Sample_ID Date Variable Batch Sample_code
# 1 123123 15/06/2019 blue 1 SAMP0001
# 2 123456 23/06/2019 red 1 SAMP0002
# 3 123123 30/06/2019 red 1 SAMP0001
# 4 123789 07/07/2019 blue 1 SAMP0003
# 5 456789 15/07/2019 blue 2 SAMP0004
# 6 123654 31/07/2019 red 2 SAMP0005
# 7 123123 12/08/2019 blue 2 SAMP0001
# 8 123789 27/08/2019 red 2 SAMP0003
# 9 121212 31/08/2019 red 2 SAMP0006