[R] simple function with if -> lapply to dataframe

Marc Schwartz marc_schwartz at comcast.net
Wed Oct 10 21:56:17 CEST 2007


On Wed, 2007-10-10 at 15:43 -0400, Georg Ehret wrote:
> Dear R,
>    I am writing a simple function to extract the sign of values and apply it
> to a data frame (see below). Whatever I do I get error-messages... What is
> wrong?
> 
> Thanking you in advance,
> Cheers, Georg.
> ***********************
> Georg Ehret
> Institute of Genetic Medicine
> Johns Hopkins University
> Baltimore
> 
> 
> > extractsign<-function(x){
> +             if (x<0) a<--1
> +             else a<-1
> +             return (a)
> +             }
> > a
>            meanSBP meanSBP_tttcorr res_asb_SBP res_asb_SBP_tttcorr meanDBP
> meanDBP_tttcorr res_asb_DBP res_asb_DBP_tttcorr
> one          -0.04           -0.01       -0.11               -0.05
> 0.18
> 0.24        0.18                0.24
> two           0.06            0.01        0.33                0.24
> 0.00
> -0.02        0.05                0.03
> three        -0.01            0.01       -0.07               -0.01
> -0.01
> 0.00       -0.05               -0.01
> four         -0.14           -0.05       -0.05                0.00
> -0.85
> -0.59       -0.79               -0.55
> five          0.12            0.06        0.17                0.07
> 0.34
> 0.21        0.60                0.44
> six          -0.06           -0.01       -0.05               -0.01
> -0.26
> -0.14       -0.41               -0.25
> > lapply(a,extractsign)
> $meanSBP
> [1] -1
> 
> $meanSBP_tttcorr
> [1] -1
> 
> $res_asb_SBP
> [1] -1
> 
> $res_asb_SBP_tttcorr
> [1] -1
> 
> $meanDBP
> [1] 1
> 
> $meanDBP_tttcorr
> [1] 1
> 
> $res_asb_DBP
> [1] 1
> 
> $res_asb_DBP_tttcorr
> [1] 1
> 
> Warning messages:
> 1: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used
> 2: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used
> 3: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used
> 4: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used
> 5: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used
> 6: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used
> 7: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used
> 8: In if (x < 0) a <- -1 else a <- 1 :
>   the condition has length > 1 and only the first element will be used

Georg,

It is because your function is not "vectorized" and you are passing
multiple values to it in lapply(). Thus, only the first value will be
used within your function.  You appear to have 8 columns, thus you get 8
errors. Also note that you are only getting one value back per column.

Rather than re-inventing the wheel, see ?sign, which is vectorized:

x <- rnorm(10)

> x
 [1] -0.51367965  0.59760260  0.09720687  0.78494269  2.67081325
 [6] -1.16379829  0.24845122  0.09277555 -0.08928070  0.17995800

> sign(x)
 [1] -1  1  1  1  1 -1  1  1 -1  1


Or for a data frame:

> head(iris)[, -5]
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1          5.1         3.5          1.4         0.2
2          4.9         3.0          1.4         0.2
3          4.7         3.2          1.3         0.2
4          4.6         3.1          1.5         0.2
5          5.0         3.6          1.4         0.2
6          5.4         3.9          1.7         0.4


> lapply(head(iris)[, -5], sign)
$Sepal.Length
[1] 1 1 1 1 1 1

$Sepal.Width
[1] 1 1 1 1 1 1

$Petal.Length
[1] 1 1 1 1 1 1

$Petal.Width
[1] 1 1 1 1 1 1



HTH,

Marc Schwartz



More information about the R-help mailing list