3

Im trying to replace the value in the Nth column of a list if a condition is true, returning the modified list.
I've tried modifying the answer from 61219 and been through most of related questions but no luck.

dataCol = {{A, 0.1, 0.3}, {B, 0.4, 0.6}, {C, 0.9, 0.9}};
cutoffFuncCol[threshold_, inputlist_,col_] := 
(inputlist[[All, col]] /. {x_ /; x > threshold -> x, x_ /; x < threshold -> 0});
cutoffFuncCol[0.5, dataCol, 2]

(* actual result {0, 0, 0.9} *)
(* Desired result  {{A, 0.0, 0.3}, {B, 0.0, 0.6}, {C, 0.9, 0.9}}; *)
Gordon Coale
  • 2,341
  • 15
  • 20
  • Your output is {0 ,0 ,.9} because you only work with dataCol[[All, 2]] which is {.1, .4., .9}. – Öskå Oct 15 '14 at 15:49

4 Answers4

4
dataCol = {{A, 0.1, 0.3}, {B, 0.4, 0.6}, {C, 0.9, 0.9}}; 

Adding the Attribute HoldRest to your cutoffFuncCol:

ClearAll[cutoffFuncColB];
SetAttributes[cutoffFuncColB, HoldRest];
cutoffFuncColB[threshold_, inputlist_, col_] := (inputlist[[All, col]] = 
    inputlist[[All, col]] /. {x_ /; x > threshold -> x, x_ /; x < threshold -> 0}; inputlist);

dataColB = dataCol; 
cutoffFuncColB[0.5, dataColB, 2]
(*  {{A, 0, 0.3}, {B, 0, 0.6}, {C, 0.9, 0.9}} *)

Using Threshold instead of ReplaceAll:

ClearAll[cutoffFuncColC];
SetAttributes[cutoffFuncColC, HoldRest];
cutoffFuncColC[threshold_, inputlist_, col_] :=
  (inputlist[[All, col]] = Threshold[inputlist[[All, col]], threshold]; inputlist);

dataColC = dataCol;
cutoffFuncColC[0.5, dataColC, 2]
(*  {{A, 0, 0.3}, {B, 0, 0.6}, {C, 0.9, 0.9}} *)

Or

ClearAll[cutoffFuncColD];
cutoffFuncColD[threshold_, inputlist_, col_] := 
 Module[{mm = inputlist},  mm[[All, col]] = Threshold[mm[[All, col]], threshold]; mm]

dataColD = dataCol;
cutoffFuncColD[0.5, dataColD, 2]
(*  {{A, 0, 0.3}, {B, 0, 0.6}, {C, 0.9, 0.9}} *)

Using Chop:

ClearAll[cutoffFuncColE];
cutoffFuncColE[threshold_, inputlist_, col_] := 
 Module[{tmp = inputlist}, tmp[[All, col]] = Chop[tmp[[All, col]], threshold]; tmp]

dataColE = dataCol;
cutoffFuncColE[0.5, dataColE, 2]
(* {{A, 0, 0.3}, {B, 0, 0.6}, {C, 0.9, 0.9}} *)

Using MapAt and UnitStep:

ClearAll[cutoffFuncColF];
cutoffFuncColF[threshold_, inputlist_, col_] := 
 Module[{mm = inputlist}, mm = MapAt[# UnitStep[# - threshold] &, mm, {All, col}]; mm]

dataColF = dataCol;
cutoffFuncColE[0.5, dataColF, 2]
(*  {{A, 0, 0.3}, {B, 0, 0.6}, {C, 0.9, 0.9}} *)

Using ReplacePart and Chop:

ClearAll[cutoffFuncColG];
cutoffFuncColG[threshold_, inputlist_, col_] := 
             ReplacePart[inputlist, {i_, col} :> Chop[inputlist[[i, col]], threshold]]

dataColG = dataCol;
cutoffFuncColG[0.5, dataColG, 2]
(*  {{A, 0, 0.3}, {B, 0, 0.6}, {C, 0.9, 0.9}} *)
kglr
  • 394,356
  • 18
  • 477
  • 896
3

To complement some of the other answers here is one using Clip

ClearAll[cutoffFuncCol];

cutoffFuncCol[threshold_, inputlist_, col_] := 
 Module[{tmp = inputlist}, 
  tmp[[All, col]] = 
   Clip[tmp[[All, col]], {threshold, \[Infinity]}, {0, \[Infinity]}];
  tmp]

cutoffFuncCol[0.5, dataCol, 2]
(* {{A, 0, 0.3}, {B, 0, 0.6}, {C, 0.9, 0.9}} *)
Mike Honeychurch
  • 37,541
  • 3
  • 85
  • 158
  • (+1) nice way to get a single-sided Clip. (The only way i could think of to get Clip to do job was Clip[#, {threshold, threshold}, {0, #}] & /@ tmp[[All, col]]) – kglr Oct 15 '14 at 21:54
  • @kguler thanks. it is amazing what you can learn here. I never knew there was Threshold but it's been there since 8! – Mike Honeychurch Oct 15 '14 at 21:56
  • @MikeHoneychurch I actually used this version as was the first I used that gave me a dynamic output, but marked Kgulers as being the most useful. – Gordon Coale Oct 16 '14 at 06:04
1

This can be nicely handled with ReplaceAt (since V 13.3)

list = {{a, 0.1, 0.3}, {b, 0.4, 0.6}, {c, 0.9, 0.9}};

ReplaceAt[x_ /; x < 0.5 :> 0, {All, 2}] @ list

{{a, 0, 0.3}, {b, 0, 0.6}, {c, 0.9, 0.9}}

cut[th_, dt_, co_] := ReplaceAt[x_ /; x < th :> 0, {All, co}] @ dt

cut[1, list, 3]

{{a, 0.1, 0}, {b, 0.4, 0}, {c, 0.9, 0}}

eldo
  • 67,911
  • 5
  • 60
  • 168
0

Using RaplaceAll:

cut[mat_, col_, rule_] := (# /. #[[All, col]] -> #[[All, col]] /. rule) &@mat

Testing cut:

cut[list, 2, x_ /; x < 0.5 :> 0]

({{a, 0, 0}, {b, 0, 0.6}, {c, 0.9, 0.9}})

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44