What is the Matlab/Octave equivalent or R's 'merge' (or 'expand.grid')? - r

I am looking for the Matlab way of doing the following:
> merge(2:4,3:7)
x y
1 2 3
2 3 3
3 4 3
4 2 4
5 3 4
6 4 4
7 2 5
8 3 5
9 4 5
10 2 6
11 3 6
12 4 6
13 2 7
14 3 7
15 4 7
> expand.grid(2:4,3:7)
Var1 Var2
1 2 3
2 3 3
3 4 3
4 2 4
5 3 4
6 4 4
7 2 5
8 3 5
9 4 5
10 2 6
11 3 6
12 4 6
13 2 7
14 3 7
15 4 7

I usually do it with meshgrid:
>> [x y] = meshgrid(2:4, 3:7);
>> [x(:) y(:)]
ans =
2 3
2 4
2 5
2 6
2 7
3 3
3 4
3 5
3 6
3 7
4 3
4 4
4 5
4 6
4 7

Use ndgrid for n variables (2 and more). For example (4-D space)
[X,Y,Z,T] = ndgrid(2:4, 3:7, 1:2, 1:10);

Related

How can I read an Elliptical Fourier Descriptor from SHAPE under the Momocs package of Rstudio?

I wish to load a CHC or NEF file from the SHAPE software in order to read the contours under MOMOCS and make the related analyses (Plot, PCA...)
I have difficulties under R as well as under the package.
How should I proceed?
Here is an extract of an outline. The first one is from a CHC and the other one from NEF.
Thank you in advance, any help is welcome.
CHC
IMG_20200710_0001_1 1045 531 1,428639E-02 46736 5 5 4 4 4 5 4 4 4 5 5 4 5 5 5 5 5 5 4 5 6 5 4 5 5 5 6 5 5 6 5 5 5 5 6 5 6 5 5 6 5 5 6 5 6 5 5 6 6 5 6 5 6 5 6 5 6 5 6 6 5 6 5 6 6 5 6 6 5 6 6 5 6 6 5 6 6 5 6 6 5 6 6 5 6 6 5 6 5 6 5 6 6 5 6 6 6 5 5 6 6 5 6 6 5 6 6 5 6 6 5 5 6 6 6 6 5 6 5 6 6 6 5 6 5 6 6 6 6 5 6 6 6 5 6 5 6 6 6 6 6 5 6 6 6 5 6 6 5 6 6 6 5 6 6 5 6 6 5 6 6 5 6 6 6 5 6 6 6 6 5 6 6 5 6 6 5 6 6 6 6 5 6 6 5 6 6 6 5 6 6 6 6 6 6 6 5 6 6 6 5 6 5 6 6 6 6 6 6 6 5 6 6 5 6 6 6 5 6 6 6 5 6 6 5 6 6 6 6 5 6 6 6 6 6 5 6 6 6 6 6 6 6 6 6 6 6 6 6 5 6 6 6 6 6 6 6 6 6 6 5 6 6 6 6 6 6 6 6 5 6 6 6 6 6 6 6 6 5 6 6 6 5 6 6 6 6 6 6 6 5 6 6 6 6 6 6 6 6 6 6 6 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 5 6 6 6 6 7 6 6 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 6 6 5 6 6 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 6 6 6 6 6 6 6 6 6 7 6 6 6 6 6 6 6 7 6 6 6 6 6 6 6 6 6 7 6 6 6 6 6 6 6 6 6 7 6 6 6 6 6 7 6 6 6 6 6 6 7 6 6 6 6 6 6 6 6 6 6 7 6 6 6 6 6 7 6 6 6 6 7 6 6 6 6 6 6 7 6 6 6 6 6 6 7 6 6 6 7 6 7 6 6 6 6 6 7 6 6 6 6 6 6 7 6 6 7 6 6 7 6 6 6 6 6 7 6 7 6 6 6 6 7 6 6 6 6 6 6 7 6 6 6 6 7 6 6 6 6 6 7 6 6 7 6 6 6 6 7 6 6 6 6 6 6 7 6 6 6 6 7 6 6 7 6 6 6 6 6 6 7 6 6 6 6 7 6 6 6 6 7 6 6 6 6 6 7 6 6 6 7 6 6 6 7 6 6 6 7 6 6 6 7 5 6 6 7 6 6 6 7 6 7 6 6 6 6 7 6 6 6 6 7 6 6 6 6 6 7 6 6 7 6 6 6 6 7 6 6 6 6 6 6 6 7 6 6 7 6 6 6 6 7 6 6 6 7 6 6 7 6 6 6 6 6 7 6 6 6 7 6 6 6 6 6 7 6 7 6 6 6 6 6 7 6 6 6 6 7 6 6 7 6 6 7 6 6 6 6 7 6 6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 1 0 2 1 1 0 0 0 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 4 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 3 3 1 2 2 4 3 1 0 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 3 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 1 2 2 2 3 1 2 2 3 2 2 2 2 2 2 2 3 1 2 2 2 2 3 1 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 3 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 1 2 2 2 2 2 2 1 2 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 2 1 2 2 1 2 2 2 2 1 2 2 2 1 2 2 2 2 1 2 2 2 1 2 2 1 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 1 2 2 1 2 2 1 2 2 2 1 2 1 1 2 2 2 2 1 2 2 1 2 2 1 2 2 2 1 2 2 1 2 2 2 1 2 2 1 2 2 2 1 2 2 1 2 2 2 1 2 2 2 1 2 2 2 2 1 0 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 3 1 0 2 1 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 3 1 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 1 2 2 3 2 2 2 2 3 2 2 2 2 2 2 2 2 2 3 2 2 2 2 3 2 2 2 3 2 2 3 2 2 3 2 2 3 2 3 2 3 2 2 3 3 2 4 3 2 3 3 4 4 -1
NEF
#CONST 1 1 1 0
#HARMO 15
IMG_20200710_0001_1
1.0000000e+00 3.5723303e-18 -2.2782437e-17 1.4062862e-01
-3.5345700e-03 -2.9677476e-04 -7.7529255e-02 2.8661995e-02
1.0149772e-01 3.3103762e-03 1.0055048e-03 3.3982778e-02
-5.6327330e-04 -3.2074328e-03 -5.6057424e-03 4.8512662e-03
3.8131276e-02 -1.5129959e-05 2.2552160e-03 1.4017338e-02
1.1789915e-04 -2.9600305e-03 -8.4295737e-04 -3.4299796e-04
1.7271413e-02 -7.2651006e-04 -1.2037379e-04 7.6870442e-03
-2.0549746e-04 -1.3433972e-03 -1.8426509e-03 -5.7843862e-04
1.0074513e-02 -9.3238318e-04 4.8671011e-05 5.6731905e-03
-7.5994187e-04 -1.0418345e-03 -7.7574542e-04 -2.8944747e-04
6.4933570e-03 -4.0572074e-04 -7.6458810e-04 4.0939891e-03
-5.4921053e-04 -8.4817676e-04 1.6206266e-04 -4.6108536e-04
4.5195469e-03 -5.4106090e-04 1.6321172e-04 3.1721989e-03
-1.8313986e-04 -3.5979483e-04 4.8276592e-04 -9.0690768e-04
3.0959844e-03 -6.1876139e-04 -6.3948596e-04 2.2105213e-03
In Momocs version 1.3.2 installed from GitHub https://github.com/MomX/Momocs/ I see the function chc2pix() that should import SHAPE's chain codes to R. In earlier Momocs documentation (https://www.rdocumentation.org/packages/Momocs/versions/0.2-03/topics/nef2Coe), you can find (in Examples!) the function nef2Coe(). I do not see this function in the current Momocs 1.3.2 but you can copy the whole function to your R script or save it to .txt and call it from R as source('path/to/your/NEF2COE.txt'). When the Momocs will be fully resurrected as MomX (https://momx.github.io/MomX/), perhaps the function again will be a part of the package.
sorry for the delay.
If you want to use CHC, then chc2pix is your friend indeed. You end up with an traditionnal outline as defined by its (x, y) coordinates.
For the NEF, it's "just" a simple string manipulation task. The clue pointed by #ordynets would likely work (or at least be very useful). Another option would be to go around :
# read the nef
m <- read.table("~/Desktop/nef.txt", skip=3)
# transpose to get in the "right" order
coe <- m %>% t %>% c %>% matrix(nrow=1)
# name columns to make thngs clear
colnames(coe) <- paste0(rep(LETTERS[1:4], times=nrow(m)),
rep(1:nrow(m), each=4))
# from now you can do whatever you want in Momocs
# eg rbind many to have an OutCoe, calculate the inverse EFT:
coe %>% coeff_rearrange("name") %>% coeff_split(nb.h=10) %>% efourier_i() %>% coo_plot()
(by the way, I'm still working on MomX, and such wrapper would fit in Momit but I struggle to find time to finish it).
do not hesitate to contact me directly !

spatstat deleting marks from a point pattern and subseuently the points

I am looking at the point pattern data set in spatstat anemones which has 231 points with marks attached to them which define the diameter.. I want to delete the marks and the points within the point pattern when the diameter is equal to 2
Here is the data:
>
[1] 6 4 4 6 3 3 5 3 5 4 4 6 5 3 4 7 4 6 6 5 4 4 5 3 3 6 4 5 4 4 5 3 3 5
3 4 5 8 5 4 6 5 6 4 5 3 3 4 5 6 4 4 3 4 4 6 5 4 3 6 5 3 [63] 3 6 5 3
3 2 5 7 4 4 4 3 3 4 3 6 2 6 6 3 4 3 7 6 3 4 2 7 4 5 4 4 4 6 4 3 3 3 3
6 7 3 7 3 2 4 3 5 2 3 4 4 3 3 3 6 3 4 5 3 6 3 [125] 7 5 3 3 4 4 5 4 4
6 5 3 3 3 5 3 6 5 5 4 4 3 4 4 4 4 3 4 7 4 6 5 7 6 3 6 5 4 6 4 5 4 5 3
6 3 3 6 4 6 4 4 6 3 5 3 4 6 5 5 4 5 [187] 4 3 3 4 4 4 4 5 4 5 5 5 4 6
4 4 5 3 5 4 3 4 4 4 3 4 5 5 3 3 5 3 4 5 6 2 5 2 3 2 3 3 7 5 4
thanks!
Another solution is to use the generic R command subset:
X <- subset(anemones, marks != 2)
From the question it is not quite clear whether you want to get rid of all the marks after deleting these points. In that case use unmark:
X <- unmark(X)
Correct me if I'm wrong but I'm reading this as meaning you wish to remove observations when anemones$marks is equal to 2.
If so this should do it:
updated_anemones <- anemones[!anemones$marks == 2,]

Create a new variable based on existing variable

My current dataset look like this
Order V1
1 7
2 5
3 8
4 5
5 8
6 3
7 4
8 2
1 8
2 6
3 3
4 4
5 5
6 7
7 3
8 6
I want to create a new variable called "V2" based on the variables "Order" and "V1". For every 8 items in the "Order" variable, I want to assign a value of "0" in "V2" if the varialbe "Order" has observation equals to 1; otherwise, "V2" takes the value of previous item in "V1".
This is the dataset that I want
Order V1 V2
1 7 0
2 5 7
3 8 5
4 5 8
5 8 5
6 3 8
7 4 3
8 2 4
1 8 0
2 6 8
3 3 6
4 4 3
5 5 4
6 7 5
7 3 7
8 6 3
Since my actual dataset is very large, I'm trying to use for loop with if statement to generate "V2". But my code keeps failing. I appreciate if anyone can help me on this, and I'm open to other statements. Thank you!
(Up front: I am assuming that the order of Order is perfectly controlled.)
You need simply ifelse and lag:
df <- read.table(text="Order V1
1 7
2 5
3 8
4 5
5 8
6 3
7 4
8 2
1 8
2 6
3 3
4 4
5 5
6 7
7 3
8 6 ", header=T)
df$V2 <- ifelse(df$Order==1, 0, lag(df$V1))
df
# Order V1 V2
# 1 1 7 0
# 2 2 5 7
# 3 3 8 5
# 4 4 5 8
# 5 5 8 5
# 6 6 3 8
# 7 7 4 3
# 8 8 2 4
# 9 1 8 0
# 10 2 6 8
# 11 3 3 6
# 12 4 4 3
# 13 5 5 4
# 14 6 7 5
# 15 7 3 7
# 16 8 6 3
with(dat,{V2<-c(0,head(V1,-1));V2[Order==1]<-0;dat$V2<-V2;dat})
Order V1 V2
1 1 7 0
2 2 5 7
3 3 8 5
4 4 5 8
5 5 8 5
6 6 3 8
7 7 4 3
8 8 2 4
9 1 8 0
10 2 6 8
11 3 3 6
12 4 4 3
13 5 5 4
14 6 7 5
15 7 3 7
16 8 6 3

How to input this vector (1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9) simply using seq()&rep()?

The vector (1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9)
seq() and rep() maybe can not deliver parameters.
I read the help doc but fail to find the way.
You could try
(1:5) + rep(0:4,each=5)
#[1] 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9
NOTE: (1:5) and 0:4 can be replaced by seq(1,5) and seq(0,4)
Another one:
as.vector(outer(1:5,0:4,"+"))

Sequentially reorganize a vector in R

I have a numeric element z as below:
> sort(z)
[1] 1 5 5 5 6 6 7 7 7 7 7 9 9
I would like to sequentially reorganize this element so to have
> z
[1] 1 2 2 2 3 3 4 4 4 4 4 5 5
I guess converting z to a factor and use it as an index should be the way.
You answered it yourself really:
as.integer(factor(sort(z)))
I know this has been accepted already but I decided to look inside factor() to see how it's done there. It more or less comes down to this:
x <- sort(z)
match(x, unique(x))
Which is an extra line I suppose but it should be faster if that matters.
This should do the trick
z = sort(sample(1:10, 100, replace = TRUE))
cumsum(diff(z)) + 1
[1] 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3
[26] 3 3 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6
[51] 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8
[76] 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10
Note that diff omits the first element of the series. So to compensate:
c(1, cumsum(diff(z)) + 1)
Alternative using rle:
z = sort(sample(1:10, 100, replace = TRUE))
rle_result = rle(sort(z))
rep(rle_result$values, rle_result$lengths)
> rep(rle_result$values, rle_result$lengths)
[1] 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
[26] 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6 6 6
[51] 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8
[76] 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10
rep(seq_along(rle(x)$l), rle(x)$l)

Resources