0

I have a matrix that consists of two columns and a number (n) of rows, while each row represents a point with the coordinates x and y (the two columns). This is what it looks (LINK):

V1  V2
146 17
151 19
153 24
156 30
158 36
163 39
168 42
173 44
...

now, I would like to use a subset of three consecutive points starting from 1 to do some fitting, save the values from this fit in another list, an den go on to the next 3 points, and the next three, ... till the list is finished. Something like this:

Data_Fit_Kasa_1 <- CircleFitByKasa(Data[1:3,])
Data_Fit_Kasa_2 <- CircleFitByKasa(Data[3:6,])
....
Data_Fit_Kasa_n <- CircleFitByKasa(Data[i:i+2,])

I have tried to construct a loop, but I can't make it work. R either tells me that there's an "unexpected '}' in "}" " or that the "subscript is out of bonds". This is what I've tried:

minimal runnable code

install.packages("conicfit")
library(conicfit) 

CFKasa <- NULL   
Data.Fit <- NULL

for (i in 1:length(Data)) {
  row <- Data[i:(i+2),]
  CFKasa <- CircleFitByKasa(row)
  Data.Fit[i] <- CFKasa[3]
}

RStudio Version 0.99.902 – © 2009-2016 RStudio, Inc.; Win10 Edu.

The third element of the fitted circle (CFKasa[3]) represents the radius, which is what I am really interested in. I am really stuck here, please help.

Many thanks in advance!

Best, David

  • As mentioned by Zheyuan Li you need take care of your loop running to far. First as you described your problem, I assume that Data is two dimensional so I suppose you want to have: `length(Data[,1])` instead. Second thing just run the loop until `length(Data[,1])-2` – Benjamin Mohn Oct 11 '16 at 14:41
  • My approach would be to turn the data into a three dimensional array and use `apply`. Provide a reproducible example and I might show you the details. – Roland Oct 11 '16 at 14:44
  • @Roland: 1. Do you mean something like cbind a list like [1:n] 1 1 1 2 2 2 3 3 3 4 4 4... for grouping? 2. Or something else? 3. Please forgive my stupidity. I am trying. – David Kleinhans Oct 11 '16 at 15:24
  • @Benjamin Mohn: Thank you as well. I will see if I can make it work. I also tried nrow(Data). – David Kleinhans Oct 11 '16 at 15:26
  • No. It would be easy to demonstrate my approach if you followed the advice in [this FAQ](http://stackoverflow.com/a/5963610/1412059). – Roland Oct 11 '16 at 15:27
  • @Benjamin Mohn: If I do `length(Data[,1])-2`, R tells me that "only 0's may be mixed with negative subscripts". – David Kleinhans Oct 11 '16 at 16:16
  • As mentioned by Zheyuan Li you have to add brackets here as well. so '(length(Data[,1]-2)' should do it – Benjamin Mohn Oct 12 '16 at 05:51

1 Answers1

0

Turn your data into a 3D array and use apply:

DF <- read.table(text = "V1  V2
                 146 17
                 151 19
                 153 24
                 156 30
                 158 36
                 163 39", header = TRUE)
a <- t(DF)
dim(a) <-c(nrow(a), 3, ncol(a) / 3)
a <- aperm(a, c(2, 1, 3))
# , , 1
# 
#      [,1] [,2]
# [1,]  146   17
# [2,]  151   19
# [3,]  153   24
# 
# , , 2
# 
#      [,1] [,2]
# [1,]  156   30
# [2,]  158   36
# [3,]  163   39

center <- function(m) c(mean(m[,1]), mean(m[,2]))

t(apply(a, 3, center))
#     [,1] [,2]
#[1,]  150   20
#[2,]  159   35

center(DF[1:3,])
#[1] 150  20
Roland
  • 127,288
  • 10
  • 191
  • 288
  • Ok, Ok. So you suggest to use 'CircleFitByKasa' to define a function, which you did for 'center' in this case, right? And what is 'DF' in the last step? – David Kleinhans Oct 11 '16 at 15:53
  • The original data.frame. The last step only demonstrates that apply works. – Roland Oct 11 '16 at 16:15