R: найдите и добавьте отсутствующие (/не существующие) строки во временном фрейме данных
Я борюсь со следующим.
Если у вас есть (большой) кадр данных со следующим:
- несколько столбцов, для которых комбинация столбцов является "уникальной" комбинацией, например идентификатор
- связанный со временем столбец
- связанный с измерением столбец
Я хочу убедиться, что для каждого уникального идентификатора для каждого временного интервала в кадре данных доступна мера. И если это не так, я хочу добавить меру 0 (или NA) для этого времени /ID.
Чтобы проиллюстрировать проблему, создайте следующий кадр данных test
:
test <- data.frame(
YearWeek =rep(c("2012-01","2012-02"),each=4),
ProductID =rep(c(1,2), times=4),
CustomerID =rep(c("a","b"), each=2, times=2),
Quantity =5:12
)[1:7,]
YearWeek ProductID CustomerID Quantity
1 2012-01 1 a 5
2 2012-01 2 a 6
3 2012-01 1 b 7
4 2012-01 2 b 8
5 2012-02 1 a 9
6 2012-02 2 a 10
7 2012-02 1 b 11
8-я строка не используется специально. Таким образом, я имитирую "недостающее значение" (отсутствует Quantity
) для идентификатора "2-b" (ProductID-CustomerID
) для значения времени "2012-02".
Что я хочу сделать, так это отредактировать data.frame таким образом, чтобы для всех значений времени (они известны в этом примере только "2012-01" и "2012-02" ), для всех ID-комбинаций (они неизвестны заранее, но это "все уникальные комбинации идентификаторов в кадре данных", таким образом, уникальный набор в столбцах идентификатора), количество доступно в кадре данных.
Это должно привести к этому примеру (если мы выберем NA
для отсутствующего значения, обычно я хочу иметь контроль над этим):
YearWeek ProductID CustomerID Quantity
1 2012-01 1 a 5
2 2012-01 2 a 6
3 2012-01 1 b 7
4 2012-01 2 b 8
5 2012-02 1 a 9
6 2012-02 2 a 10
7 2012-02 1 b 11
8 2012-02 2 b NA
Конечная цель - создать временные ряды для этих комбинаций идентификаторов, и поэтому я хочу иметь количество для всех значений времени. Мне нужно выполнить различные агрегации (по времени) и использовать разные уровни идентификатора из большого набора данных
Я попробовал несколько вещей, например melt
и cast
из пакета reshape
. Но пока мне это не удалось. Следующим шагом является создание функции с помощью for-loops и т.д., Но это не очень полезно с точки зрения производительности.
Возможно, есть более простой способ мгновенного создания временных рядов, дающий data.frame как test
. У кого-нибудь есть идея об этом?
Спасибо заранее!
Обратите внимание, что в реальной задаче имеется более двух "столбцов идентификаторов".
EDIT:
Я должен описать проблему дальше. Существует разница между столбцом "время" и столбцами "ID". Первый (и большой!) Ответ на вопрос joran, возможно, не получил ясного понимания из того, что я хочу (и пример, который я дал, не сделал разницы ясными). Я сказал выше:
для всех ID-комбинаций (они не известны заранее, но это все уникальные комбинации идентификаторов в кадре данных ", таким образом, уникальный набор на Идентификаторы)
Поэтому мне не нужны "все возможные комбинации идентификаторов", но "все идентификационные комбинации в данных".
Для каждой из этих комбинаций я хочу значение для каждого уникального значения времени.
Позвольте мне пояснить, расширяя test
до test2
следующим образом
> test2 <- rbind(test, c("2012-02", 3, "a", 13))
> test2
YearWeek ProductID CustomerID Quantity
1 2012-01 1 a 5
2 2012-01 2 a 6
3 2012-01 1 b 7
4 2012-01 2 b 8
5 2012-02 1 a 9
6 2012-02 2 a 10
7 2012-02 1 b 11
8 2012-02 3 a 13
Это означает, что я хочу, чтобы в результирующем фрейме данных не было идентификатора "3-b", потому что эта комбинация не находится в пределах test2
. Если я использую метод первого ответа, я получу следующее:
> vals2 <- expand.grid(YearWeek = unique(test2$YearWeek),
ProductID = unique(test2$ProductID),
CustomerID = unique(test2$CustomerID))
> merge(vals2,test2,all = TRUE)
YearWeek ProductID CustomerID Quantity
1 2012-01 1 a 5
2 2012-01 1 b 7
3 2012-01 2 a 6
4 2012-01 2 b 8
5 2012-01 3 a <NA>
6 2012-01 3 b <NA>
7 2012-02 1 a 9
8 2012-02 1 b 11
9 2012-02 2 a 10
10 2012-02 2 b <NA>
11 2012-02 3 a 13
12 2012-02 3 b <NA>
Поэтому я не хочу, чтобы строки 6
и 12
были здесь.
Чтобы преодолеть эту проблему, я нашел решение в приведенном ниже. Здесь я разделяю "уникальный столбец времени" и "уникальную комбинацию идентификаторов". Таким образом, разница с выше - это слово "комбинация", а не уникальное для каждого столбца идентификатора.
> temp_merge <- merge(unique(test2["YearWeek"]),
unique(test2[c("ProductID", "CustomerID")]))
> merge(temp_merge,test2,all = TRUE)
YearWeek ProductID CustomerID Quantity
1 2012-01 1 a 5
2 2012-01 1 b 7
3 2012-01 2 a 6
4 2012-01 2 b 8
5 2012-01 3 a <NA>
6 2012-02 1 a 9
7 2012-02 1 b 11
8 2012-02 2 a 10
9 2012-02 2 b <NA>
10 2012-02 3 a 13
Каковы комментарии к этому?
Это элегантный способ, или есть ли лучшие способы?
Ответы
Ответ 1
Используйте expand.grid
и merge
:
vals <- expand.grid(YearWeek = unique(test$YearWeek),
ProductID = unique(test$ProductID),
CustomerID = unique(test$CustomerID))
> merge(vals,test,all = TRUE)
YearWeek ProductID CustomerID Quantity
1 2012-01 1 a 5
2 2012-01 1 b 7
3 2012-01 2 a 6
4 2012-01 2 b 8
5 2012-02 1 a 9
6 2012-02 1 b 11
7 2012-02 2 a 10
8 2012-02 2 b NA
NA
можно заменить после факта с любыми значениями, которые вы выбираете, используя подмножество и is.na
.