У меня есть сбалансированный фрейм данных в длинном формате (df1), который состоит из 7 столбцов:
df1 <- structure(list(Product_ID = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3), Product_Category = structure(c(1L, 1L, 1L, 1L, 1L,
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L), .Label = c("A", "B"), class = "factor"),
Manufacture_Date = c(1950, 1950, 1950, 1950, 1950, 1960,
1960, 1960, 1960, 1960, 1940, 1940, 1940, 1940, 1940), Control_Date = c(1961L,
1962L, 1963L, 1964L, 1965L, 1961L, 1962L, 1963L, 1964L, 1965L,
1961L, 1962L, 1963L, 1964L, 1965L), Country_Code = structure(c(1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), .Label = c("ABC",
"DEF", "GHI"), class = "factor"), Var1 = c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), Var2 = c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA,
15L), class = "data.frame")
Каждый Product_ID в этом наборе данных связан с уникальными Product_Category и Country_Code и Manufacture_Date и сопровождается время (Control_Date). Product_Category имеет два возможных значения (A или B); Country_Code и Manufacture_Date имеют 190 и 90 уникальных значений соответственно. Существует 400 000 уникальных Product_ID, за которыми следуют в течение 50 лет (Control_Date с 1961 по 2010 год). Это означает, что df1 имеет 20 000 000 строк. Последние два столбца этого фрейма данных в начале имеют значение NA и должны быть заполнены данными, доступными в другом фрейме данных (df2):
df2 <- structure(list(Product_ID = 1:6, Product_Category = structure(c(1L,
2L, 1L, 1L, 1L, 2L), .Label = c("A", "B"), class = "factor"),
Manufacture_Date = c(1950, 1960, 1940, 1950, 1940, 2000),
Country_Code = structure(c(1L, 2L, 3L, 1L, 2L, 3L), .Label = c("ABC",
"DEF", "GHI"), class = "factor"), Year_1961 = c(5, NA, 10,
NA, 6, NA), Year_1962 = c(NA, NA, 4, 5, 3, NA), Year_1963 = c(8,
6, NA, 5, 6, NA), Year_1964 = c(NA, NA, 9, NA, 10, NA), Year_1965 = c(6,
NA, 7, 4, NA, NA)), row.names = c(NA, 6L), class = "data.frame")
Этот второй фрейм данных содержит другой тип информации о Точно такие же 400 000 продуктов, в широкоформатном формате. Каждая строка представляет уникальный продукт (Product_ID), сопровождаемый его Product_Category, Manufacture_Date и Country_Code. Есть 50 других столбцов (для каждого года с 1961 по 2010 год), которые содержат измеренное значение (или NA) для каждого продукта в каждый из этих лет.
Теперь я хотел бы заполнить Столбцы Var1 и Var2 в первом кадре данных, выполнив некоторые вычисления для данных, доступных во втором кадре данных. Точнее, для каждой строки в первом фрейме данных (т. Е. Для продукта с Control_Date "t") последние два столбца определяются следующим образом:
Var1: общее количество товаров в df2 с той же Product_Category, Manufacture_Date и Country_Code, которые имеют значение, отличное от NA, в Year_t;
Var2: общее количество товаров в df2 с другой категорией_категории, но одинаковыми Manufacture_Date и Country_Code, которые имеют значение не-NA в Year_t.
Мое первоначальное решение с использованием вложенных циклов for выглядит следующим образом:
for (i in unique(df1$Product_ID)){
Category <- unique(df1[which(df1$Product_ID==i),"Product_Category"])
Opposite_Category <- ifelse(Category=="A","B","A")
Manufacture <- unique(df1[which(df1$Product_ID==i),"Manufacture_Date"])
Country <- unique(df1[which(df1$Product_ID==i),"Country_Code"])
ID_Similar_Product <- df2[which(df2$Product_Category==Category & df2$Manufacture_Date==Manufacture & df2$Country_Code==Country),"Product_ID"]
ID_Quasi_Similar_Product <- df2[which(df2$Product_Category==Opposite_Category & df2$Manufacture_Date==Manufacture & df2$Country_Code==Country),"Product_ID"]
for (j in unique(df1$Control_Date)){
df1[which(df1$Product_ID==i & df1$Control_Date==j),"Var1"] <- length(which(!is.na(df2[which(df2$Product_ID %in% ID_Similar_Product),paste0("Year_",j)])))
df1[which(df1$Product_ID==i & df1$Control_Date==j),"Var2"] <- length(which(!is.na(df2[which(df2$Product_ID %in% ID_Quasi_Similar_Product),paste0("Year_",j)])))
}
}
Проблема этого подхода заключается в том, что для его запуска требуется много времени. Поэтому я хотел бы знать, может ли кто-нибудь предложить векторизованную версию, которая сделает работу за меньшее время.