Given a column of data (of the type 39600.432, 39600.433, etc) I would like to drop the integer part of the number and keep only the decimals (transforming 39600.432 into 432, and 39600.433 into 433). How can I do this?
Let's say your column is the vector x.
> x <- c(39.456, 976.902)
> x <- x - as.integer(x)
> x
[1] 0.456 0.902
That should work. You can then just multiply by 1000 to convert the current x to integers. You will need some more processing if you want 3.9 to become 9.
> x <- 1000*x
> x
[1] 456 902
Hope the helps!
Many good answers, here's one more using regular expressions.
> g <- c(134.3412,14234.5453)
> gsub("^[^\\.]*\\.", "", g)
[1] "3412" "5453"
To strip the integral part without a subtraction or regex, you can use the modulus operator.
x <- (10000:10010)/100
x
## [1] 100.00 100.01 100.02 100.03 100.04 100.05 100.06 100.07 100.08 100.09 100.10
x %% 1
## [1] 0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10
%% 1 is meaningful in R. This does leave the value as fractional, which may not be ideal for your use.
You are looking for the floor function. But you could do as.integer as well.
Here is an approach using regular expressions
g<-c(134.3412,14234.5453)
r<-regexpr("[0-9]+$",g)
as.numeric(regmatches(g,r))
This should do it:
g <- c(134.3412,14234.5453)
h <- floor(g)
g - h
Related
I have numeric's like this one:
a <- -1.542045
And I want to round them down (or round up the abs) to 2 digits after the decimal point.
signif(a,3) will round it down and give me 1.54 as a result but for this example the result I want is -1.55.
Any idea?
I think you are looking for floor(a * 100) / 100.
Quick Test
a <- c(-1.542045, 1.542045)
floor(a * 100) / 100
# [1] -1.55 1.54
I just noticed that you changed your question 7 hours ago. Then my answer is not doing exactly what you want (as I am assuming by "rounding down" you always want to round toward -Inf). But I have discussed this in first version of my answer. Now I am going to copy those relevant back here.
With sign(a) * ceiling(abs(a) * 100) / 100 you can round data toward Inf for positive values and -Inf for negative values.
With sign(a) * floor(abs(a) * 100) / 100, you round both positive and negative values toward 0.
A quick test
a <- c(-1.542045, 1.542045)
sign(a) * ceiling(abs(a) * 100) / 100
# [1] -1.55 1.55
sign(a) * floor(abs(a) * 100) / 100
# [1] -1.54 1.54
You misunderstand the issue. If the value is in -1.542045, it will always be.
Now you can print it to two decimals or get a two decimal char:
> print(a, digits=3)
[1] -1.54
> format(a, digits=3)
[1] "-1.54"
>
Should you really desire to create a new representation you can:
> b <- trunc(a*1e2)*1e-2
> b
[1] -1.54
>
A preferable way may be
> b <- round(a, digits=2)
> b
[1] -1.54
>
A combination of ceiling(), abs() and sign() can be used to round up the abs of the number, irrespective of its sign. Such a rounding at two decimal digits can be obtained with:
ceiling(abs(a)*100)/100*sign(a)
Example:
a <- c(-1.542045, 1.542045)
ceiling(abs(a)*100)/100*sign(a)
#[1] -1.55 1.55
In math, we can approximate a number such this:
Suppose we have x and y with these values:
x = 0.35
and
y=0.67
Then the approximate of x and y are, x=0.4 and y=0.7.
I would like to know how to do this in r.
round function seems to be unable to deal with this issue.
With round :
x <- 0.35
round(x,digits=1)
# [1] 0.4
The function round it works good, the way you need to use it is that you need to put the digits like:
x <- 0.34
round(x, digits = 1)
# [1] 0.3
x <- 0.37
round(x, digits = 1)
# [1] 0.4
I have numeric's like this one:
a <- -1.542045
And I want to round them down (or round up the abs) to 2 digits after the decimal point.
signif(a,3) will round it down and give me 1.54 as a result but for this example the result I want is -1.55.
Any idea?
I think you are looking for floor(a * 100) / 100.
Quick Test
a <- c(-1.542045, 1.542045)
floor(a * 100) / 100
# [1] -1.55 1.54
I just noticed that you changed your question 7 hours ago. Then my answer is not doing exactly what you want (as I am assuming by "rounding down" you always want to round toward -Inf). But I have discussed this in first version of my answer. Now I am going to copy those relevant back here.
With sign(a) * ceiling(abs(a) * 100) / 100 you can round data toward Inf for positive values and -Inf for negative values.
With sign(a) * floor(abs(a) * 100) / 100, you round both positive and negative values toward 0.
A quick test
a <- c(-1.542045, 1.542045)
sign(a) * ceiling(abs(a) * 100) / 100
# [1] -1.55 1.55
sign(a) * floor(abs(a) * 100) / 100
# [1] -1.54 1.54
You misunderstand the issue. If the value is in -1.542045, it will always be.
Now you can print it to two decimals or get a two decimal char:
> print(a, digits=3)
[1] -1.54
> format(a, digits=3)
[1] "-1.54"
>
Should you really desire to create a new representation you can:
> b <- trunc(a*1e2)*1e-2
> b
[1] -1.54
>
A preferable way may be
> b <- round(a, digits=2)
> b
[1] -1.54
>
A combination of ceiling(), abs() and sign() can be used to round up the abs of the number, irrespective of its sign. Such a rounding at two decimal digits can be obtained with:
ceiling(abs(a)*100)/100*sign(a)
Example:
a <- c(-1.542045, 1.542045)
ceiling(abs(a)*100)/100*sign(a)
#[1] -1.55 1.55
There are several posts on computing pairwise differences among vectors, but I cannot find how to compute all differences within a vector.
Say I have a vector, v.
v<-c(1:4)
I would like to generate a second vector that is the absolute value of all pairwise differences within the vector. Similar to:
abs(1-2) = 1
abs(1-3) = 2
abs(1-4) = 3
abs(2-3) = 1
abs(2-4) = 2
abs(3-4) = 1
The output would be a vector of 6 values, which are the result of my 6 comparisons:
output<- c(1,2,3,1,2,1)
Is there a function in R that can do this?
as.numeric(dist(v))
seems to work; it treats v as a column matrix and computes the Euclidean distance between rows, which in this case is sqrt((x-y)^2)=abs(x-y)
If we're golfing, then I'll offer c(dist(v)), which is equivalent and which I'm guessing will be unbeatable.
#AndreyShabalin makes the good point that using method="manhattan" will probably be slightly more efficient since it avoids the squaring/square-rooting stuff.
Let's play golf
abs(apply(combn(1:4,2), 2, diff))
#Ben, yours is a killer!
> system.time(apply(combn(1:1000,2), 2, diff))
user system elapsed
6.65 0.00 6.67
> system.time(c(dist(1:1000)))
user system elapsed
0.02 0.00 0.01
> system.time({
+ v <- 1:1000
+ z = outer(v,v,'-');
+ z[lower.tri(z)];
+ })
user system elapsed
0.03 0.00 0.03
Who knew that elegant (read understandable/flexible) code can be so slow.
A possible solution is:
z = outer(v,v,'-');
z[lower.tri(z)];
[1] 1 2 3 1 2 1
I just started working with R and would like to get a Nonlinear least square fit nls(...) to the formula y=A(1-exp(-bL))+R.
I define my function g by
> g<-function(x,y,A,b,R) {
y~A(1-exp(-bx))+R
}
and want to perform nls by
>nls((y~g(x,y,A,b,R)),data=Data, start=list(A=-2,b=0,R=-5))
And I end with the following error message.
>Error in lhs - rhs : non-numeric argument to binary operator
I guess it's just a stupid basic mistake by another beginner, but I'd be extremely glad if anyone could help me out.
Next question would be, whether I can implement the fitted curve into my graph
>plot(x,y,main="VI.20.29")
Thanks to everyone taking time to read and hopefully answer my question!
Detailed information:
I have a table with the x values (Light.intensity) and y values (e.g. VI.20.29)
> photo.data<-read.csv("C:/X/Y/Z.csv", header=T)
> names(photo.data)
[1] "Light.intensity" "SR.8.6" "SR.8.7"
[4] "SR.8.18" "SR.8.20" "VI.20.1"
[7] "VI.20.5" "VI.20.20" "VI.20.29"
[10] "DP.19.1" "DP.19.15" "DP.19.33"
[13] "DP.19.99"
> x<-photo.data$Light.intensity
> x
[1] 0 50 100 200 400 700 1000 1500 2000
> y<-photo.data$VI.20.29
> y
[1] -2.76 -2.26 -1.72 -1.09 0.18 0.66 1.47 1.48 1.63
> plot(x,y,main="VI.20.29")
> Data<-data.frame(x,y)
> Data
x y
1 0 -2.76
2 50 -2.26
3 100 -1.72
4 200 -1.09
5 400 0.18
6 700 0.66
7 1000 1.47
8 1500 1.48
9 2000 1.63
> g<-function(x,y,A,b,R) {
+ y~A(1-exp(-bx))+R
+ }
> nls((y~g(x,y,A,b,R)),data=Data, start=list(A=-2,b=0,R=-5))
Error in lhs - rhs : non-numeric argument to binary operator
The problem is that you're calling a function within a function. You're saying y~g(...), when the function g(...) itself calls y~(other variables). It's kind of 'double counting' in a way.
Just do:
nls(y~A*(1-exp(-b*x))+R, data=Data, start=list(A=-2,b=0,R=-5))
Your initial guess for parameters were way off. I saved your data in 'data.csv'
for this example that converges and then does the plot... To get this, I
adjusted parameters to get close and then did the nls fit...
df <- read.csv('data.csv')
x <- df$x
y <- df$y
plot(x,y)
fit <- nls(y~A*(1-exp(-b*x))+R, data=df, start=list(A=3,b=0.005,R=-2))
s <- summary(fit)
A <- s[["parameters"]][1]
b <- s[["parameters"]][2]
R <- s[["parameters"]][3]
f <- function(z){
v <- A*(1-exp(-b*z))+R
v
}
x.t <- 0:max(x)
y.c <- sapply(x.t, f)
lines(x.t, y.c, col='red')
print(s)
Computers do what you tell them:
y~A(1-exp(-bx))+R
Here R interprets A(...) as a function and bx as a variable.
You want y~A*(1-exp(-b*x))+R.