Reputation: 109
I'm trying to round an output from a simple by()
function in R
. This is what I have:
> by(glaciers[,1:3],glaciers$activity.level,mean)
glaciers$activity.level: Active
aspect sun.duration latitude
-9.444444e+00 1.771778e+03 3.247643e+09
-------------------------------------------
glaciers$activity.level: Inactive
aspect sun.duration latitude
1.041667e+01 2.067583e+03 4.048301e+09
-------------------------------------------
glaciers$activity.level: Relict
aspect sun.duration latitude
1.766667e+01 2.168000e+03 2.759283e+09
How can I get my output to round to say 5 decimal places, and still keep the factors?
I've tried: round(by(glaciers[,1:3],glaciers$activity.level,mean),5)
but get an error: Non-numeric argument to mathematical function
.
Upvotes: 8
Views: 15743
Reputation: 31800
by(glaciers[,1:3], glaciers$activity.level, function(x){round(mean(x),5)})
UPDATE
Here is a working example:
glaciers <- as.data.frame(matrix(rnorm(1000),ncol=4))
glaciers[,4] <- sample(0:3,250,replace=TRUE)
colnames(glaciers) <- c("A","B","C","activity.level")
by(glaciers[,1:3], glaciers$activity.level, function(x){round(mean(x),5)})
Upvotes: 4
Reputation: 44862
If you already have the output saved to a variable, say x:
x <- by(glaciers[,1:3],glaciers$activity.level,mean)
Then apply round() to each element (the output of by() in this case is a list).
x[] <- lapply(x,round,5)
x
reassigning to x[] rather than x allows x to retain attributes attached to it from by().
Edit: round() actually changes the value of the variables but is decoupled from its printing. If you want to suppress the scientific notation output format, use format="f" argument to formatC()
> round(1.2345e10,5)
[1] 1.2345e+10
> formatC(1.2345e10,digits=5,format="f")
[1] "12345000000.00000"
So the correction to the expression originally posted would be
x[] <- lapply(x,formatC,digits=5,format="f")
Upvotes: 10
Reputation: 3662
You asked "How can I get my output to round to say 5 decimal places?" but I think what you meant was "How can I get my output to show say 6 significant figures?" The following code combines two of the previous answers -- the idea of reassigning to res[], and the use of signif rather than round.
glaciers <- data.frame(aspect=runif(20)*100,
sun.duration=runif(20)*10000,
latitude=runif(20)*10^9,
activity.level=sample(c('Active','Inactive','Relict'),20,replace=TRUE))
res <- by(glaciers[,1:3],glaciers$activity.level,mean)
res[] <- lapply(res,signif,3)
res
This code produces the following output:
glaciers$activity.level: Active
aspect sun.duration latitude
3.66e+01 4.72e+03 4.56e+08
-------------------------------------------------
glaciers$activity.level: Inactive
aspect sun.duration latitude
5.81e+01 5.28e+03 4.83e+08
-------------------------------------------------
glaciers$activity.level: Relict
aspect sun.duration latitude
6.08e+01 4.75e+03 3.98e+08
Upvotes: 2
Reputation: 100144
round()
doesn't make sense in this instance, since you're working with very large numebrs. You want to use the format() command, and choose how many digits to display. For instance, to show 3 significant digits:
by(glaciers[,1:3], glaciers$activity.level, function(x) {
as.numeric(format(mean(x), digits=3))
})
Upvotes: 6
Reputation: 27339
Only have a couple of minutes, but you might try looking at the format()
, formatC()
, and prettyNum()
functions. Their help files look like gibberish to me right now, but I haven't slept much. However, I did use one of these functions - most likely formatC()
- for a Sweave report some months ago in which I needed very specifically formatted numbers.
Upvotes: 1
Reputation: 19361
Do you want to round or to just truncate the number of digits shown? If the latter, use options(digits=3) or whatever.
> by(mpg[,8:9], mpg$cyl, mean)
mpg$cyl: 4
cty hwy
21.012 28.802
------------------------------------------------------------
mpg$cyl: 5
cty hwy
20.50 28.75
------------------------------------------------------------
mpg$cyl: 6
cty hwy
16.215 22.823
------------------------------------------------------------
mpg$cyl: 8
cty hwy
12.571 17.629
> options(digits=3)
> by(mpg[,8:9], mpg$cyl, mean)
mpg$cyl: 4
cty hwy
21.0 28.8
------------------------------------------------------------
mpg$cyl: 5
cty hwy
20.5 28.8
------------------------------------------------------------
mpg$cyl: 6
cty hwy
16.2 22.8
------------------------------------------------------------
mpg$cyl: 8
cty hwy
12.6 17.6
Upvotes: 1