zinon
zinon

Reputation: 4664

Can't read correctly the value type of dataframe elements

I have a data frame

SSIM_BEST=    
    X1 X2       X3 X4  X5
1    1 36 0.939323 B4  ON
2    1 35 0.943645 B2  ON
3    1 34 0.948516 B2  ON
4    1 33 0.952599 ZL  ON
5    1 32 0.956492 ZL  ON
6    1 31 0.960432 ZL  ON
7    1 30 0.963957 ZL  ON
8    1 29  0.96664 ZL  ON
9    1 28 0.969612 ZL  ON
10   1 27  0.97234 ZL  ON
11   1 26  0.97478 ZL  ON
12   1 25 0.977332 ZL  ON
13   1 24 0.979606 ZL  ON
14   1 23 0.981423 ZL  ON
15   1 22 0.983776 ZL  ON

I have for loop to read some values from X3 column, like:

SSIM=c()

for (j in seq(1,dim(SSIM_BEST)[1], by=2)) {
  SSIM= c(SSIM, SSIM_BEST$X3[[j]]))
}

Instead of getting values like 0.939323,0.948516... I get SSIM=20 27 33 39 44 52 56 61 and I don't know what is going on.

In case I use print(SSIM_BEST$X3[[j]]) in the for-loop I get something like:

[1] 0.939323 72 Levels: 0.894559 0.899583 0.901154 0.907706 0.914609 0.914673 0.91996 0.920569 0.922076 0.925761 0.925897 0.926495 0.928728 0.931108 ... 0.992964

P.S. SSIM_BEST contains more than 15 rows. I show 15 here for example purposes.

Can you help me please?

Upvotes: 0

Views: 41

Answers (2)

Chase Grimm
Chase Grimm

Reputation: 425

I think its because SSIM_BEST$X3 is a factor. I'm willing to bet the values you get from the for loop are the levels of the factors.

I have a couple options that should both work.

SSIM=c()
SSIM_BEST$X3 <- as.numeric(SSIM_BEST$X3)

for (j in seq(1,dim(SSIM_BEST)[1], by=2)) {
  SSIM= c(SSIM, SSIM_BEST$X3[[j]]))
}

Or

SSIM=c()

for (j in seq(1,dim(SSIM_BEST)[1], by=2)) {
  SSIM= c(SSIM, as.numeric(SSIM_BEST$X3[[j]])))
}

As Frank said, for loops are not good. I wrote a simple function that can do what you want without a for loop.

getDat <- function(data,by=2,start=1) {

  v <- (1:length(data) %% by == 1)

  if(start > 1){
    v <- c(v,rep(F,start-1))
    v <- shift(v,start-1)
    is.na(v) <- FALSE
    v <- v[1:(length(v) - (start-1))]
  }

  data <- data[v]
  data[!is.na(data)]
}

This also allows you to specify where to start in the vector.

x <- 1:50
 getDat(x,2)
 [1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49
getDat(x,2,2)
 [1]  2  4  6  8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50
getDat(x,3,10)
[1] 10 13 16 19 22 25 28 31 34 37 40 43 46 49

Upvotes: 0

zx8754
zx8754

Reputation: 56159

We can create TRUE/FALSE vector to subset.

# data
SSIM_BEST <- read.table(text ="
  X1 X2       X3 X4  X5
1    1 36 0.939323 B4  ON
2    1 35 0.943645 B2  ON
3    1 34 0.948516 B2  ON
4    1 33 0.952599 ZL  ON
5    1 32 0.956492 ZL  ON
6    1 31 0.960432 ZL  ON
7    1 30 0.963957 ZL  ON
8    1 29  0.96664 ZL  ON
9    1 28 0.969612 ZL  ON
10   1 27  0.97234 ZL  ON
11   1 26  0.97478 ZL  ON
12   1 25 0.977332 ZL  ON
13   1 24 0.979606 ZL  ON
14   1 23 0.981423 ZL  ON
15   1 22 0.983776 ZL  ON", header = TRUE)

# get odd rows
SSIM_BEST[c(TRUE, FALSE), "X3"]

# more generic solution
mySkip = 2
SSIM_BEST[seq(nrow(SSIM_BEST)) %% mySkip == 1, "X3"]

Upvotes: 2

Related Questions