Как добавить символы в строки разного размера при подготовке к объединению фреймов данных через left_join?

У меня есть база DF под названием help.a и я пытаюсь присоединиться help.bОднако, когда я читаю в help.b переменная id является числовой и не имеет такую ​​же длину / формат, как переменная id в help.a, Я пытаюсь придерживаться символьных переменных, потому что left_join меняет их на символьные, когда уровни фактора различны.

help.a <- data.frame(id = as.character(c("00005", "00010", "00010", "00010", "00025", "00025", "00324", "00324")),
                       var_a = c(NA, 2, 2, 2, NA, NA, NA, NA),
                       var_b = c(4, NA, NA, 4, 4, 4, NA, NA))

help.b <- data.frame(id = c(5, 10, 324),
                         var_c = c(2, 2, 2),
                         var_d = c(4, NA, 6))

До сих пор мой подход состоял в том, чтобы изменить help.b на символ, однако он не может присоединиться из-за несовпадения идентификаторов:

help.b$id <- as.character(help.b$id)
left_join(help.a, help.b)

     id var_a var_b var_c var_d
1 00005    NA     4    NA    NA
2 00010     2    NA    NA    NA
3 00010     2    NA    NA    NA
4 00010     2     4    NA    NA
5 00025    NA     4    NA    NA
6 00025    NA     4    NA    NA
7 00324    NA    NA    NA    NA
8 00324    NA    NA    NA    NA

Это мой желаемый конечный результат:

     id var_a var_b var_c var_d
1 00005    NA     4     2     4
2 00010     2    NA     2    NA
3 00010     2    NA     2    NA
4 00010     2     4     2    NA
5 00025    NA     4    NA    NA
6 00025    NA     4    NA    NA
7 00324    NA    NA     2     6
8 00324    NA    NA     2     6

И что я думаю, что мне нужно сделать, это прочитать в help.b и измените id на символ, а затем добавьте "0" к каждому идентификатору, но все должны равняться 5 символам в длину... например, строке 1 потребуется четыре "0", а строке 2 потребуется три "0". Таким образом, left_join заметит совпадающие строки и присоединится соответствующим образом.

Любая помощь очень ценится.

2 ответа

Решение

Похоже, вы ищете sprintf:

help.b$id <- sprintf("%05d", help.b$id)

С d вы указываете, что вы хотите отформатировать целые числа, с 05 что вы хотите, чтобы результирующее число было шириной 5 символов, дополненное нулями.

Из комментариев видно, что help.b$id столбец символов В этом случае, в зависимости от платформы (в Linux это не работает; sprintf не говорит, на каких платформах это работает), вы можете использовать

help.b$id <- sprintf("%05s", help.b$id)

Или же,

# When help.b$id is a character use
id <- as.numeric(help.b$id)
# When help.b$id is a factor use
id <- as.numeric(as.character(help.b$id))

# Just to make sure check the conversion went ok; should return empty vector and
# if not the values for which the conversion went wrong.
help.b$id[as.character(id) != help.b$id]

help.b$id <- sprintf("%05d", id)

Один из вариантов здесь - просто преобразовать help.a$id столбец в числовой, а затем использовать baseR merge() функция в LEFT JOIN Режим (all.x=TRUE):

> help.a$id <- as.numeric(as.character(help.a$id))

> merge(help.a, help.b, by="id", all.x=TRUE)
   id var_a var_b var_c var_d
1   5    NA     4     2     4
2  10     2    NA     2    NA
3  10     2    NA     2    NA
4  10     2     4     2    NA
5  25    NA     4    NA    NA
6  25    NA     4    NA    NA
7 324    NA    NA     2     6
8 324    NA    NA     2     6

Обновить:

Если по какой-то причине вы хотите сохранить исходный столбец, просто создайте его копию в help.a кадр данных, например

help.a$id_orig <- help.a$id

Сделайте это перед преобразованием help.a$id к числовому.

Другие вопросы по тегам