# Replace matrix with conditions

I want to replace the values of 1. in slot under the condition that the year and month in basevalue and slot have to be matched

Here are my matrices:

basevalue = {{{2012, 9}, 0.2819}, {{2012, 10}, 1.01406}, {{2012, 11}, 1.06447}, {{2012, 12}, 0.929704}, {{2013, 1}, 1.11471}, {{2013, 2}, 1.08585}}

slot = {{{2012, 3}, 1.}, {{2012, 4}, 1.}, {{2012, 5}, 1.}, {{2012, 6}, 1.}, {{2012, 7}, 1.}, {{2012, 8}, 1.}, {{2012, 9}, 1.}, {{2012, 10}, 1.}, {{2012, 11}, 1.}, {{2012, 12}, 1.}, {{2013, 1}, 1.}, {{2013, 2}, 1.}}

I have tried the following code by my own

Map[Function[arg, ReplacePart[arg, 2 -> Select[basevalue, #[[1]] == arg[[1]] &][[All, -1]] ]], slot] , but it returned me different from what I want.

I think I still do not fully understand how to use function :(

Any helps or suggestions would be appreciated

Thank you

newslot=Replace[slot,
Rule @@@ Cases[GatherBy[Join[slot, basevalue], First], {_, _}], 1]


If you want only those in the slot list with a 1. "blank" to be replaced (i.e., if there can be members of slot that have a matching date in the basevalue list, but not a 1. in the "blank" position), use:

Replace[slot,
Rule @@@ Cases[GatherBy[Join[Cases[slot, {_, 1.}], basevalue], First], {_, _}], 1]


and a sneaky way that is probably faster for large lists (assuming you want sort by date and with caveat re: comments):

Sort[DeleteDuplicates[Join[basevalue, slot], #2[[1]] == #1[[1]] &]]


and as long as the slot/basevalue follow some basic rules, a goofy-fast solution:

Transpose[{slot[[All, 1]], Extract[SparseArray[Join[Rule @@@ basevalue, Rule @@@ slot]],
slot[[All, 1]]]}]


for the terse fans:

slot /. ({#[[1]], 1.} -> # & /@ basevalue)

• I think the second code returns differently from the first one if you have more period (month) in basevalue than slot. – newbie Mar 4 '14 at 4:43
• @newbie: Of course. If you have a replacement list that has "keys" not a subset of the target, that method is a no-go. I assumed from OP that replacements are for some existing set. Added caveat to answer... – ciao Mar 4 '14 at 4:50
• Thank you very much for your help. If I understand correctly the first one is more strict since Cases only picks the one that existing in basevalue. – newbie Mar 4 '14 at 4:53
• @newbie: yes, the first is the most general (or strict, depending on your semantics): it will only replace entries in the slots that exist in basvalues. Your post implies the target has 1. as the "blank", if that's not always the case, might want to say so in your OP, since these methods assume basically that (i.e., if the "date" matches in the target, replace the "blank" (1.) with a new value). – ciao Mar 4 '14 at 4:58
• @newbie: I want to be sure my answer is responsive to your question. If not, I'll happily jigger it or delete it. If an answer does fit your needs, you can mark it or comment as such. I didn't think the question ambiguous, but I'm wondering if I misinterpreted it. – ciao Mar 4 '14 at 6:01

Just for variety:

Module[{w},
SortBy[Last@
Reap[Sow[#2, w[#1]] & @@@ Join[basevalue, slot], _,
First /@ {#1, #2} &], First]]


yields:

{{{2012, 3}, 1.}, {{2012, 4}, 1.}, {{2012, 5}, 1.}, {{2012, 6},
1.}, {{2012, 7}, 1.}, {{2012, 8}, 1.}, {{2012, 9},
0.2819}, {{2012, 10}, 1.01406}, {{2012, 11}, 1.06447}, {{2012, 12},
0.929704}, {{2013, 1}, 1.11471}, {{2013, 2}, 1.08585}}