How to plot a function involving summation and logs in R - r

How to plot in R the following function
$l(\theta) = ln(\theta)*\sum{y_i} -n*\theta -n*ln(1-e^{-\theta})-\sum{ln(y_i!)}$
where the summations are from $i=1$ to $n$
I have the data set, but I know how to enter that already.

Something like this:
L <- function(theta, y){
log(theta)*sum(y) -
length(y) *(theta + log(1 - exp(-theta))) -
sum(lfactorial(y))
}
L_theta <- function(theta){
L(theta, y)
}
#example
y <- c(1, 3, 5, 7)
L(2, y)
# [1] -11.4324
plot(L_theta, xlim=c(0, 2), xlab="θ" )
producing something like

Related

Simple way in R to generate an output matrix Z from input vectors x,y and a user defined function f(x,y)

I am new to R. As simple as the question sounds, I haven't been able to find a simple way of doing it in the documentation. So far, the best way I've come up, to generate Z is the below. But surely there is some built in function.
Example for the function
grid_size <- 10
x <- seq(0,1,length.out =grid_size)
y <- seq(0,1,length.out =grid_size)
xgrid <- matrix(x, nrow=grid_size, ncol=grid_size, byrow=TRUE)
ygrid <- matrix(x, nrow=grid_size, ncol=grid_size, byrow=FALSE)
f2v <- function(xgrid, ygrid) {
return (1 - xgrid + xgrid*ygrid)
}
Z <- f2v(xgrid, ygrid)
Thank you.
Use outer:
grid_size <- 10
x <- seq(0 ,1, length.out = grid_size)
y <- seq(0, 1, length.out = grid_size)
t(outer(x, y, function(x,y) 1 - x + x*y))

Creating a function in R but getting a replacement has length zero error

I tried to create a function f and create the function so when a value x is inserted, it spits out a function f from y.But, when I try to run the code to plot, it gives me an error that says that my y_value has no length.
f <- function(x){
if (x<0){
print(y_values<-x*x*x)
}
if(x>0 & x<=1){
print(y_values<-x*x)
}
if(x>1){
print(y_values<-sqrt(x))
}
}
x_values <- seq(-2, 2, by = 0.1)
y_values <- rep(NA, length(x_values))
for (i in seq_along(x_values)) {
x <- x_values[i]
y_values[i] <- f(x)
}
# output
plot(x_values, y_values, type = "l")
Two issues:
From ?print
‘print’ prints its argument and returns it invisibly (via
‘invisible(x)’)
So all your function f does is print the values to the console (instead of returning them).
As per your definition of f, the function does not know how to deal with x=0; so this will create a problem when you store the output of f(0) later.
We can fix these issues by slightly altering f as
f <- function(x) {
y_values <- NA
if (x<0){
y_values<-x*x*x
}
if(x>0 & x<=1){
y_values<-x*x
}
if(x>1){
y_values<-sqrt(x)
}
return(y_values)
}
Then
x_values <- seq(-2, 2, by = 0.1)
y_values <- rep(NA, length(x_values))
for (i in seq_along(x_values)) {
x <- x_values[i]
y_values[i] <- f(x)
}
plot(x_values, y_values, type = "l")
You could also use Vectorize to obtain a vectorised function f2, which allows you to pass x_values as a vector, thereby avoiding the explicit for loop:
f2 <- Vectorize(f)
x_values <- seq(-2, 2, by = 0.1)
y_values <- f2(x_values)
The resulting plot is the same.
I would recommend you explore other methods for coding something like this:
here is one option that doesn't use a for loop. If you are simply working on using for loops then the fix Mauritus Evers made should work for you.
library(tidyverse)
data.frame(x_values = seq(-2, 2, by = 0.1)) %>%
mutate(y_values = case_when(x_values < 0 ~ x_values^3,
x_values>=0 & x_values<=1 ~ x_values^2,
x_values>1 ~ sqrt(x_values))) %>%
ggplot(aes(x_values, y_values)) + geom_point()
note that I changed your code to produce output when x_value = 0.

Contour plots using functions in R

In the following code I'm trying to use the function norm.dem to generate a contour plot of the points given by x and y. I can't seems to figure out how to do this. I've tried everything I could think of. For some reason the function isn't letting me put in values of sequence. Shouldn't the outer function give me a list of values?
x=seq(-10,10,length=1000)
y=seq(-10,10,length=1000)
sigma <- matrix(c(10,-5,-5,20), ncol=2)
sigma
norm.den=function(x,y,sigma,mu)
{
j<-c(x,y)
k=j-mu
t<-t(k)
s<-solve(sigma)
d<-det(sigma)
((2.718)^(-t%*%s%*%k/2))/(2*(3.14)*sqrt(d))
}
z=outer(x,y,norm.den,sigma=sigma,mu=c(0,0))
Forcibly using for() loops works.
normden <- function(x, y, solvsig=ss, detsig=ds, mu=c(0, 0)) {
k <- c(x, y) - mu
tk <- t(k)
(exp(-tk %*% ss %*% k / 2)) / (2*pi*sqrt(ds))
}
sigma <- matrix(c(10, -5, -5, 20), ncol=2)
ss <- solve(sigma)
ds <- det(sigma)
x <- seq(-10, 10, length=10)
y <- seq(-10, 10, length=10)
z <- array(dim=c(length(x), length(x)))
for(i in seq(x)) {
for(j in seq(y)) {
z[i, j] <- normden(x=x[i], y=y[j])
}}
z
I couldn't get outer() to work with the normden() function. Don't know why.
outer(x, y, "normden")
I get the same error that the OP mentioned, Error in -tk %*% ss : non-conformable arguments.

Lebesgue–Stieltjes Integration in R

I calculated a distribution function numerically. First I plot the function. It looks wrong around 0.05. Is this due to rounding errors, please?
Second, I need to find the corresponding first and second non-central moments. That is,
EX = int x dF(x)
EX^2 = int x^2 dF(x)
Can I do this type of Lebesgue–Stieltjes integration in R, please? Is there a build-in method, please? If not in R, what package offers such calculation, please?
I guess alternatively, I can find the numerical differentiation f(x) of F(x) and then conduct the usually integration like
EX = int x f(x) dx
But I remember from somewhere that numerical differentiation is much less stable. Which is the right way, please?
FYI my functions are attached below.
library(mvtnorm)
library(matrixcalc)
VAR <- matrix(c(1.043856e-03, 5.044899e-04, 3.239951e-04, 2.330992e-04, 0.0001779055, 0.0001403866, 0.0001127118, 9.074962e-05, 7.157144e-05,
5.044899e-04, 5.485889e-04, 3.523165e-04, 2.534751e-04, 0.0001934568, 0.0001526582, 0.0001225642, 9.868232e-05, 7.782773e-05,
3.239951e-04, 3.523165e-04, 3.878844e-04, 2.790645e-04, 0.0002129870, 0.0001680697, 0.0001349376, 1.086447e-04, 8.568475e-05,
2.330992e-04, 2.534751e-04, 2.790645e-04, 3.123147e-04, 0.0002383642, 0.0001880950, 0.0001510153, 1.215896e-04, 9.589399e-05,
1.779055e-04, 1.934568e-04, 2.129870e-04, 2.383642e-04, 0.0002728857, 0.0002153361, 0.0001728863, 1.391990e-04, 1.097820e-04,
1.403866e-04, 1.526582e-04, 1.680697e-04, 1.880950e-04, 0.0002153361, 0.0002548851, 0.0002046389, 1.647645e-04, 1.299447e-04,
1.127118e-04, 1.225642e-04, 1.349376e-04, 1.510153e-04, 0.0001728863, 0.0002046389, 0.0002555744, 2.057751e-04, 1.622886e-04,
9.074962e-05, 9.868232e-05, 1.086447e-04, 1.215896e-04, 0.0001391990, 0.0001647645, 0.0002057751, 2.840218e-04, 2.239993e-04,
7.157144e-05, 7.782773e-05, 8.568475e-05, 9.589399e-05, 0.0001097820, 0.0001299447, 0.0001622886, 2.239993e-04, 3.974881e-04),
nrow=9, ncol=9, byrow=TRUE)
is.symmetric.matrix(VAR)
is.positive.definite(VAR)
kappa(VAR)
CDF <- function(x){
summand <- rep(0, 5)
for(j in 5:9){
choice <- combn(9, j)
for(i in 1:ncol(choice)){
ub <- rep(Inf, 9)
ub[choice[, i]] <- x
summand[j-4] <- summand[j-4] + as.numeric(pmvnorm(lower=rep(-Inf, 9), upper=ub, sigma=VAR))
}
}
l <- c(1, -5, 15, -35, 70)
as.numeric(t(l)%*%summand)
}
CDF <- Vectorize(CDF)
x <- seq(-0.1, 0.1, by=0.01)
y <- CDF(x)
plot(x, y, type="l", lwd=2)
I initially plotted the result I got from taking first differences from numCDF <- CDF( seq(-10, 10, length=100) ), but that was rather disappointing, since only one value was different than 0. So I restricted the focus to:
numCDF <- CDF( seq(-.10, .10, length=100) )
plot( diff(numCDF) )
Simply plotting the values of numCDF produces similar chaotic results in the region where you expressed concern.
So I think maybe your function is not sufficiently well-behaved to yield good results.

Function for normalizing one data frame to be applied on a second data frame in R

This is home work.
I am new to R.
I have two data frames each containing two columns of data. I have to find a function that normalize the first data frame to a mean of 0 and a variance of 1 - for both columns. Then I want to apply that function on the second data frame.
I have tried this:
my_scale_test <- function(x,y) {
apply(y, 2, function(x,y) {
(y - mean(x ))/sd(x)
})
}
where x is the first data frame and y is the data frame to be normalized.
Can some one help me?
Edit:
I have now tried this aswell, but not working either:
scale_func <- function(x,y) {
xmean <- mean(x)
xstd <- sd(x)
yout <- y
for (i in 1:length(x[1,]))
yout[,i] <- yout[,i] - xmean[i]
for (i in 1:length(x[1,]))
yout[,i] <- yout[,i]/xsd[i]
invisible(yout)
}
Edit 2:
I found this working function for MatLab (which i tried to translate in edit 1):
function [ Xout ] = scale( Xbase, Xin )
Xmean = mean(Xbase);
Xstd = std(Xbase);
Xout = Xin;
for i=1:length(Xbase(1,:))
Xout(:,i) = Xout(:,i) - Xmean(i);
end
for i=1:length(Xbase(1,:))
Xout(:,i) = Xout(:,i)/Xstd(i);
end
end
Can someone help me translate it?
Since you are new to R, let's try something really basic.
my_scale_test <- function(x, y) {
y.nrow <- nrow(y)
x.mean <- data.frame(t(apply(x, 2, mean)))
x.sd <- data.frame(t(apply(x, 2, sd)))
# To let x.mean and x.sd have the same dimension as y, let's repeat the rows.
x.mean <- x.mean[rep(1, y.nrow), ]
x.sd <- x.sd[rep(1, y.nrow), ]
(y - x.mean)/x.sd
}
To test, try
set.seed(1)
x <- data.frame(matrix(rnorm(10), nrow = 5))
y <- x
result <- my_scale_test(x, y)
apply(result, 2, mean)
apply(result, 2, sd)

Resources