Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match data.table/data.frame with matrix that partially matches

I am trying to merge the following data.table:

DE <- structure(list(date1 = c("2000", "2001", "2003"), country = c("DE", 
"DE", "DE"), value = c(10, 20, 30)), row.names = c(NA, -3L), class = c("data.table", 
"data.frame"))

   date1 country value
1:  2000      DE    10
2:  2001      DE    20
3:  2003      DE    30 

I want to merge this with a matrix with 0's:

df <- structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), .Dim = 6:5, .Dimnames = list(
    c("2000", "2001", "2002", "2003", "2004", "2005"), c("UK", 
    "DE", "FR", "SP", "IT")))

     UK DE FR SP IT
2000  0  0  0  0  0
2001  0  0  0  0  0
2002  0  0  0  0  0
2003  0  0  0  0  0
2004  0  0  0  0  0
2005  0  0  0  0  0

such that the desired outputs is as follows:

     UK DE  FR SP IT
2000  0  10  0  0  0
2001  0  20  0  0  0
2002  0  0   0  0  0
2003  0  30  0  0  0
2004  0  0   0  0  0
2005  0  0   0  0  0
like image 432
brokkoo Avatar asked Dec 08 '25 12:12

brokkoo


2 Answers

We can use row/column indexing to assign the 'value' column from 'DE' to 'df'

df[DE$date1, DE$country] <- DE$value

-output

> df
     UK DE FR SP IT
2000  0 10  0  0  0
2001  0 20  0  0  0
2002  0  0  0  0  0
2003  0 30  0  0  0
2004  0  0  0  0  0
2005  0  0  0  0  0
like image 146
akrun Avatar answered Dec 11 '25 03:12

akrun


This is a real contrast to master akrun's solution. It is obvious that it is not comparable to his solution. For learning purposes my thoughts:

  1. df is a matrix, array class. So bring it to a dataframe class, not tibble as tibbles do not accept rownames.
  2. pivot_wider and add a right_join
  3. Then do some tweaking, where mutate(DE = coalesce(DE.x,DE.y), .keep="unused", .before=4) I really love.
  4. bring back the rownames
library(dplyr)
library(tidyr)

df <- df %>% 
    as.data.frame() %>%  
    rownames_to_column("date1")

DE %>% 
    pivot_wider(
    names_from = country,
    values_from = value
    ) %>% 
    right_join(df, by="date1") %>% 
    arrange(date1) %>% 
    mutate(DE = coalesce(DE.x,DE.y), .keep="unused", .before=4) %>% 
    column_to_rownames("date1")
     UK DE FR SP IT
2000  0 10  0  0  0
2001  0 20  0  0  0
2002  0  0  0  0  0
2003  0 30  0  0  0
2004  0  0  0  0  0
2005  0  0  0  0  0
like image 27
TarJae Avatar answered Dec 11 '25 03:12

TarJae