Создать столбец возрастающих значений на основе уникальных значений в другом столбце в R с новыми данными, добавляемыми в пакетах - PullRequest
1 голос
/ 28 марта 2020

Я задал похожий вопрос в Python ( Как создать столбец возрастающих значений на основе уникальных значений в другом столбце в pandas) и получил скрипт работающим, но по разным причинам Мне нужно добиться того же в R сейчас. Я также добавляю здесь сложность желания периодически добавлять новые наборы данных в набор данных.

У меня есть список образцов с уникальными номерами образцов ("Sample_ID"). Каждый ряд набора данных является образцом. Некоторые образцы дублируются несколько раз. Я хочу создать новый набор имен семплов («Sample_code»), который увеличивается с 1, когда вы go вниз строк с префиксом (например, «SAMP00001», «SAMP00002» и c). Я хочу, чтобы порядок строк был сохранен (так как они примерно в порядке даты сбора образцов). А для дублированных выборок я хочу, чтобы номер, заданный для Sample_code, соответствовал первой строке, в которой появляется идентификатор образца, а не строкам, расположенным ниже по таблице (которые появились позже при сборе образцов).

Мои начальные данные проиллюстрированы с помощью 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

Я хочу создать столбец Sample_code, показанный в df1b:

# 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 должны учитывать любые дубликаты Sample_ID, которые присутствовали в df1, но также не должны изменять ни одно из имен 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 партии сэмплов таким же образом, et c et c.

Я ценю там как минимум 2 этапа этой проблемы: 1) создание восходящего списка имен Sample_code с использованием уникальных значений Sample_ID; и 2) Создание итеративным способом добавления партий образцов. Но поскольку вторая точка влияет на функциональность, которую я хочу для имен Sample_code, я включил здесь оба этапа.

Наконец - в идеале я хочу использовать для этого только пакеты base R и tidyverse.

Любая помощь высоко ценится! Спасибо.

1 Ответ

0 голосов
/ 28 марта 2020

Поскольку вам необходимо знать все возможные идентификаторы образца перед назначением кода образца, рассмотрите возможность изменения порядка, вызвав rbind для всех образцов фреймов данных. Затем назначьте Sample_code , используя factor уровни. В противном случае переназначьте 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
...