Относительно слияния двух фреймов данных - PullRequest
0 голосов
/ 24 марта 2020

У меня много данных, которые представлены ниже. всего есть 13 дафафреймов, как показано ниже. Все они имеют одинаковые столбцы.

Пример данных

Всего в каждом кадре данных содержится около 500 000 строк и 106 столбцов. Я хочу объединить их следующим образом:

Если первый И второй столбец в строке в df1 равен первому и второму столбцу в строке, то я df2, я хочу добавить две строки вместе, в противном случае я хочу добавить строку в фрейм данных.

Я создал следующий код для минимального примера (который дает мне желаемый результат, но на самом деле не будет работать для масштаба, над которым я работаю):

dput(df1[,1:5 ]) 
structure(list(C5id = c("100110", "100110", "100110", "100110", 
"100100", "100100", "100100", "100100", "100100", "100100"), 
    Retnavn = c("Braiserede kæber af gris, tomat-skysovs, kartofler, ovnbagte bønner med bacon", 
    "Braiseret okseinderlår, skysovs, kartofler, marinerede rødløg med hyldeblomst", 
    "Cremet champignonsuppe", "Forårsfrikassé med kalv, asparges og forårsløg, kartofler, broccoli", 
    "Hakkebøf, bearnaisesauce, kartofler, ærter", "Farsbrød med gulerødder og ærter, legeret sovs, kartofler og romanescokål", 
    "Fiskefrikadeller med persillesovs, kartofler og juliennegrønt", 
    "Fiskefrikadeller med remouladesovs, kartofler og juliennegrønt", 
    "Forloren hare med vildtsovs, kartofler og tyttebærsylt", 
    "Frikadeller med skysovs, kartofler og sellerichutney"), 
    a2018uge2 = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2), a2018uge3 = c("2", 
    "2", "2", "2", "2", "2", "2", "2", "2", "2"), a2018uge4 = c("2", 
    "2", "2", "2", "2", "2", "2", "2", "2", "2")), class = "data.frame", row.names = 4:13)
> dput(df2[,1:5 ])
structure(list(C5id = c("100110", "100110", "100100", "100100", 
"100100", "100100", "100100", "100100", "100100", "100100", "100110", 
"100110", "100100", "100100", "100100", "100100", "100100"), 
    Retnavn = c("Braiserede kæber af gris, tomat-skysovs, kartofler, ovnbagte bønner med bacon", 
    "Braiseret okseinderlår, skysovs, kartofler, marinerede rødløg med hyldeblomst", 
    "Cremet champignonsuppe", "Forårsfrikassé med kalv, asparges og forårsløg, kartofler, broccoli", 
    "Hakkebøf, bearnaisesauce, kartofler, ærter", "Hamburgerryg, flødekartofler, blomkål, broccoli og romanesco", 
    "Kylling i karrysovs med æbler og ingefær, kartofler, cherrytomater med løg", 
    "Kylling i sur-sød sovs med peberfugt, kartofler og broccoli", 
    "Kyllingefrikassé med kartofler", "Lammesteg, flødekartofler, ovnbagte grønne bønner med bacon", 
    "Cremet champignonsuppe", "Forårsfrikassé med kalv, asparges og forårsløg, kartofler, broccoli", 
    "Farsbrød med gulerødder og ærter, legeret sovs, kartofler og romanescokål", 
    "Fiskefrikadeller med persillesovs, kartofler og juliennegrønt", 
    "Fiskefrikadeller med remouladesovs, kartofler og juliennegrønt", 
    "Forloren hare med vildtsovs, kartofler og tyttebærsylt", 
    "Frikadeller med skysovs, kartofler og sellerichutney"), 
    a2018uge2 = c(3, 3, 1, 1, 3, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 
    2, 2), a2018uge3 = c("3", "3", "1", "1", "3", "1", "1", "1", 
    "1", "1", "2", "2", "2", "2", "2", "2", "2"), a2018uge4 = c("3", 
    "3", "1", "1", "3", "1", "1", "1", "1", "1", "2", "2", "2", 
    "2", "2", "2", "2")), class = "data.frame", row.names = c("5", 
"6", "7", "8", "9", "10", "11", "12", "13", "14", "61", "71", 
"91", "101", "111", "121", "131"))


df2_before = df2
hej=c()
for (i in 1:length(df2$C5id)) {
  for (j in 1:length(df1$C5id)) {
    if (df2$C5id[i] == df1$C5id[j]  &&  df2$Retnavn[i] == df1$Retnavn[j]) {
      df2[j, 3:8 ] <- as.numeric(df2[i,3:8 ]) + as.numeric(df1[j,3:8 ])
      hej=c(hej,j)
      #df1 = df1[-i, ]
    }
  }
  cat("vi er kommet til:",i,",",j,"\n")
}
df2=rbind(df2,df1[-hej,])

где df1 и df2 - два кадра данных. Моя проблема заключается в том, что это должно составлять от oop до 500.000 * 500.000 различных комбинаций. В общей сложности у меня есть 13 фреймов данных такого размера, которые должны быть объединены, поэтому я бы взял абсолютную вечность.

Я надеялся, что будет какой-то векторизованный способ для этого, который может быть сделан до падения 2030.

С наилучшими пожеланиями

пс. Я понимаю, что способ, которым я вставил данные в этот пост, может быть не самым лучшим. Но это может быть лучшее, что я могу подумать о

pps. Я редактировал вопрос относительно комментария МКР.

1 Ответ

1 голос
/ 30 марта 2020

Я предлагаю следующее:

library(data.table)
df1 <- data.table::setDT(df1)
df2 <- data.table::setDT(df2)
data.table::setkeyv(df1, c("C5id","Retnavn"))
data.table::setkeyv(df2, c("C5id","Retnavn"))

new_df2 <- merge(df1,df2, all.y = TRUE)
cols <- names(new_df2[,3:ncol(new_df2)])
new_df2[, (cols) := lapply(.SD, as.numeric), .SDcols = cols]
new_df2[, (cols) := lapply(.SD, function(i)
                           tidyr::replace_na(i,0)), .SDcols = cols]

sapply(new_df2, class)

Таким образом, вы преобразовали свою переменную в число c:

      C5id     Retnavn a2018uge2.x a2018uge3.x a2018uge4.x a2018uge2.y a2018uge3.y a2018uge4.y 
"character" "character"   "numeric"   "numeric"   "numeric"   "numeric"   "numeric"   "numeric"

Затем, опираясь на эту проблему: R: объединение столбцы и значения, если они имеют одинаковое имя столбца с решением @bgoldst:

# First I replace the names of the same variables by replacing ".x" or ".y":
names(new_df2) <- stringr::str_replace(names(new_df2),".[xy]","")

temp = do.call(cbind,lapply(split(as.list(new_df2[,3:ncol(new_df2)]),
                                  names(new_df2[,3:ncol(new_df2)])),
                            function(x) Reduce(`+`,x)));

new_df2 <- cbind(new_df2[,1:2],temp)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...