Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Substitute values in a data.frame with values from another data.frame

Tags:

dataframe

r

So, I have this data.frame, let's call it df1, that looks like this

   r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12
1   1  2  2  2  0  2  1  2  0   2   1   2
2   0  2  2  2  2  2  0  2  0   2   2   2
3   1  2  2  2  0  2  2  2  2   1   2   2
4   1  2  2  2  2  1  2  2  2   1   2   2
5   0  1  2  2  0  2  1  0  0   1   1   0
6   0  2  0  2  0  2  2  0  0   2   2   2
7   1  2  2  2  2  2  2  0  0   1   2   2
8   0  2  2  2  2  2  2  2  2   2   2   2
9   0  2  2  2  2  2  1  1  1   1   1   2

and one, let's call it df2, that looks like this

         r1         r2             r3             r4            r5 ...
1 arp1_base melo1_base      son_clave     melo2_base   melo3_major ...
2   arp1_v1   melo1_v1    rumba_clave melo2_staccato   melo3_minor ...
3   arp1_v2   melo1_v2 rumba_clave_v1  melo2_contour melo3_contour ...

I'm not pasting all the columns here but you get the idea (and yes, the numbers of rows are different).

Now I need to replace the numbers in each column of the first data.frame with the value from the second data.frame matching the column and using the numbers in the first data.frame as a row index for the second data.frame. What I'd like to have is a new data.frame that would look like this:

         r1         r2             r3 ...
1   arp1_v1   melo1_v2 rumba_clave_v1 ...
2 arp1_base   melo1_v2 rumba_clave_v1 ...
3   arp1_v1   melo1_v2 rumba_clave_v1 ...
.         .          .              .
.         .          .              .
.         .          .              .

How do I do that? Ideally each new column would be a factor that retains the three names as levels.

And by the way, I feel like this is kind of a FAQ, but I'm faced with the usual n00b problem of having no clue as to what to google. Is there any kind of magic around that?

EDIT As per @akrun's suggestion below, I can do df1[] <- Map(function(x, y) factor(y[x+1]), df1, df2) and I get almost what I want, in the sense that the columns of df1 are now factors with the substituted values, but I'd need each of these factors to have as levels all the values from the corresponding column in df2.

like image 604
Morpheu5 Avatar asked Nov 26 '25 05:11

Morpheu5


1 Answers

Try

  df1[] <- Map(function(x, y) y[x+1], df1, df2)
  df1
  #       r1       r2             r3            r4            r5
  #1   arp1_v1 melo1_v2 rumba_clave_v1 melo2_contour   melo3_major
  #2 arp1_base melo1_v2 rumba_clave_v1 melo2_contour melo3_contour
  #3   arp1_v1 melo1_v2 rumba_clave_v1 melo2_contour   melo3_major
  #4   arp1_v1 melo1_v2 rumba_clave_v1 melo2_contour melo3_contour
  #5 arp1_base melo1_v1 rumba_clave_v1 melo2_contour   melo3_major
  #6 arp1_base melo1_v2      son_clave melo2_contour   melo3_major
  #7   arp1_v1 melo1_v2 rumba_clave_v1 melo2_contour melo3_contour
  #8 arp1_base melo1_v2 rumba_clave_v1 melo2_contour melo3_contour
  #9 arp1_base melo1_v2 rumba_clave_v1 melo2_contour melo3_contour

Update

To create the columns as factor with levels equal to levels of corresponding columns of df2

  df1[] <-  Map(function(x, y) factor(y[x+1], levels=unique(y)), df1, df2)
  levels(df1[,1])
  #[1] "arp1_base" "arp1_v1"   "arp1_v2"  

data

 df1 <- structure(list(r1 = c(1L, 0L, 1L, 1L, 0L, 0L, 1L, 0L, 0L), r2 = c(2L, 
 2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L), r3 = c(2L, 2L, 2L, 2L, 2L, 0L, 
 2L, 2L, 2L), r4 = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), r5 = c(0L, 
 2L, 0L, 2L, 0L, 0L, 2L, 2L, 2L)), .Names = c("r1", "r2", "r3", 
 "r4", "r5"), class = "data.frame", row.names = c("1", "2", "3", 
 "4", "5", "6", "7", "8", "9"))

 df2 <- structure(list(r1 = c("arp1_base", "arp1_v1", "arp1_v2"), 
  r2 = c("melo1_base", "melo1_v1", "melo1_v2"), r3 = c("son_clave",
  "rumba_clave", "rumba_clave_v1"), r4 = c("melo2_base", "melo2_staccato",
  "melo2_contour"), r5 = c("melo3_major","melo3_minor", "melo3_contour")),
 .Names = c("r1", "r2", "r3", "r4", "r5"), class = "data.frame", 
 row.names = c("1", "2", "3"))
like image 175
akrun Avatar answered Nov 28 '25 19:11

akrun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!