[R] replace numbers in a column conditional on their value

Rolf Turner r.turner at auckland.ac.nz
Wed Jan 16 20:45:33 CET 2008


On 17/01/2008, at 5:45 AM, Jabez Wilson wrote:

> Dear R help,
>
>   I have a data frame column in which I would like to replace some  
> of the numbers dependent on their value.
>
>   data frame = zz
>
>   AveExpr         t      P.Value       FC
> 7.481964  7.323950 1.778503e-04 2.218760
> 7.585783 12.233056 6.679776e-06 2.155867
> 6.953215  6.996525 2.353705e-04 1.685733
> 7.647513  8.099859 9.512639e-05 1.674742
> 7.285446  7.558675 1.463732e-04 1.584071
> 6.405605  3.344031 1.276812e-02 1.541569
>
>   I would like to replace the values in column 'FC' which are >2  
> with their squared value.
>   If I do this, however, I get a warning but it does the sum  
> correctly.
>   Warning message:
> number of items to replace is not a multiple of replacement length  
> in: zz[, 4][zz[, 4] > 2] <- zz[, 4]^2
>
>   Is there a way to do this without the warning?

Other replies have suggested a better way to do this, but have not  
made it clear
what you are doing wrong.  The problem is that in your example you  
are effectively
trying to replace 2 values with a vector of length 6 (i.e. zz[,4] 
^2).  This will
use the first two values of the vector of length 6 to replace the two  
values that
you've chosen to replace.

This ``works'' in your example since your two values to be replaced  
come first in
the column.  But it *won't* work in general, warning message or no  
warning message.

E.g.

zz <- data.frame(x=1:6,y=1:6,z=1:6,w=c(1,2,3,3,2,1))
  > zz
   x y z w
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 3
5 5 5 5 2
6 6 6 6 1
R > zz[,4][zz[,4]>2] <- zz[,4]^2
Warning message:
In zz[, 4][zz[, 4] > 2] <- zz[, 4]^2 :
   number of items to replace is not a multiple of replacement length
  > zz
   x y z w
1 1 1 1 1
2 2 2 2 2
3 3 3 3 1
4 4 4 4 4
5 5 5 5 2
6 6 6 6 1

The two values (3rd and 4th) to be replaced got replaced by 1 and 4  
--- the squares
of the first two entries of the column.

Moral of the story:  ***DON'T SUPPRESS WARNINGS***!!!  ***HEED  
THEM***!!!

The use of ifelse that others have suggested is the right way to go.   
But
you could do what you want using a syntax similar to that which you  
indeed used,
but corrected as follows:

  > zz <- data.frame(x=1:6,y=1:6,z=1:6,w=c(1,2,3,3,2,1))
  > zz[,4][zz[,4]>2] <- zz[,4][zz[,4]>2]^2 # See the difference?
  > zz
   x y z w
1 1 1 1 1
2 2 2 2 2
3 3 3 3 9
4 4 4 4 9
5 5 5 5 2
6 6 6 6 1

	cheers,

		Rolf Turner



######################################################################
Attention:\ This e-mail message is privileged and confid...{{dropped:9}}




More information about the R-help mailing list