У меня есть несколько лет данных с уникальными справочными кодами, я хочу отслеживать, как справочные коды появляются в данных с течением времени, есть ли у кого-нибудь способ сделать это? Я приведу пример того, что я ищу.
Вот как могут выглядеть данные:
2005 г. | 2006 г. | 2007 г. |
---|---|---|
92837503 | 75482342 | 54654656 |
34923478 | 13049483 | 98769879 |
..... | ..... | ..... |
09340823 | 2304923 | 0988775 |
и что я хочу сделать, так это сопоставить уникальные ссылки за эти годы и оставить пробелы там, где они могут не появиться:
2005 г. | 2006 г. | 2007 г. |
---|---|---|
92837503 | 92837503 | 92837503 |
34923478 | нет | 34923478 |
..... | ..... | ..... |
09340823 | нет | нет |
нет | 2304923 | нет |
Какова ваша структура входных данных? Они все в одном фрейме данных? Или отдельные кадры/векторы данных для каждого года? Это кажется довольно простой full_join
операцией, но ее трудно понять, не понимая, что вы вводите. Ваш пример странный, потому что ваш ввод имеет 2005 и 2006 годы, а ваш вывод также имеет 2007 год, казалось бы, из ниоткуда...
Пожалуйста, поделитесь небольшим, но воспроизводимым примером ввода, либо с кодом R для создания объекта, либо с dput()
(который создает код R для создания объекта, например, dput(your_data[1:5, ])
для первых 5 строк фрейма данных с именем your_data
).
@GregorThomas на данный момент они находятся в отдельных фреймах данных, только с данными за один год и одним столбцом.
Отлично. Пожалуйста, поделитесь несколькими строками из 3 фреймов данных воспроизводимо. dput(your_2005_data[1:5, , drop = FALSE])
, dput(your_2006_data[1:5, , drop = FALSE])
, dput(your_2007_data[1:5, , drop = FALSE])
. Затем мы можем протестировать код, чтобы решить вашу проблему. Мы, вероятно, захотим собрать все соответствующие фреймы данных в list
, поэтому, если есть шаблон в том, как они названы, было бы полезно знать.
Это может быть не самый простой/быстрый способ, но мой метод будет заключаться в повороте/развороте.
library(tidyverse)
data %>%
pivot_longer(cols = colnames(data), #this assumes that only your years are the columns in the data.
names_to = "year",
values_to = "code") %>%
mutate(id_code = code) %>% #This will line up the codes on the same row in the next step.
pivot_wider(id_cols = "id_code",
names_from = "year",
values_from = "code",
values_fill = NULL #This will ensure that all the missing values are the same, change if appropriate.
) %>%
select(-id_code) #drop the id column if no longer required.
Я думаю, что это было бы проще, чем использовать соединения, но могут быть и лучшие способы, кто-то может прийти с решением rowwise().
код
library(data.table)
Reduce(f = function(x, y) merge(x, y, by = c("i"), all = T), lapply(list(df1, df2, df3), function(x) setDT(x)[, i := x[, 1L]]))
Пример данных
df1 <- data.frame(`2005` = c(1,3,6,7,12))
df2 <- data.frame(`2006` = c(12,2,4,7,10))
df3 <- data.frame(`2007` = c(4,100))
полученные результаты
# i X2005 X2006 X2007
# 1: 1 1 NA NA
# 2: 2 NA 2 NA
# 3: 3 3 NA NA
# 4: 4 NA 4 4
# 5: 6 6 NA NA
# 6: 7 7 7 NA
# 7: 10 NA 10 NA
# 8: 12 12 12 NA
# 9: 100 NA NA 100
детальное объяснение
Здесь один лайнер разбивается на три строки (шага).
Вы упомянули, что ваши data.frames хранятся отдельно, поэтому мы добавляем их в список.
dfs <- list(df1, df2, df3)
Затем мы применяем к каждой из ваших таблиц в списке и создаем универсальный столбец, который мы можем объединить позже, столбец будет называться «i». setDT
превращает data.frame
s в data.table
, а i := x[x, 1L]
гарантирует, что значение i будет вашим значением.
dfs <- lapply(dfs, function(x) setDT(x)[, i := x[, 1L]])
Затем мы можем использовать базовую функцию Reduce
, чтобы объединить список таблиц в универсальном столбце i. Функция сокращения имеет два значения: x — это предыдущий результат (объединение), а y — новое значение (следующая таблица для слияния).
Reduce(f = function(x, y) merge(x, y, by = c("i"), all = T), dfs)
Ваш пример не ясен. Почему
928...
повторяется через все 3 года выпуска, а349...
нет?