Why Does Sapply Return a Matrix That I Need to Transpose, and Then The Transposed Matrix Will Not Attach to a Dataframe

Why does sapply return a matrix that I need to transpose, and then the transposed matrix will not attach to a dataframe?

To expand on DWin's answer: it would help to look at the structure of your out object. It explains why b$var1/b$var2 doesn't do what you expect.

> out <- sapply(a$id, function(x) out = a[x, c('var1', 'var2')])
> str(out) # this isn't a data.frame or a matrix...
List of 6
$ : num 1
$ : num 3
$ : num 2
$ : num 2
$ : num 3
$ : num 1
- attr(*, "dim")= int [1:2] 2 3
- attr(*, "dimnames")=List of 2
..$ : chr [1:2] "var1" "var2"
..$ : NULL

The apply family of functions are designed to work on vectors and arrays, so you need to take care when using them with data.frames (which are usually lists of vectors). You can use the fact that data.frames are lists to your advantage with lapply.

> out <- lapply(a$id, function(x) a[x, c('var1', 'var2')])  # list of data.frames
> out <- do.call(rbind, out) # data.frame
> b <- cbind(b,out)
> str(b)
'data.frame': 3 obs. of 4 variables:
$ var3: num 0 0 0
$ var1: num 1 2 3
$ var2: num 3 2 1
$ var3: num 0 0 0
> b$var1/b$var2
[1] 0.3333333 1.0000000 3.0000000

Why my function always mistakenly returns a transposed matrix as output?

Your result is assembled by apply, and it's apply that shapes the output (using, of course, your desc_n function along the way).

From the ?apply help page:

If each call to FUN returns a vector of length n, and simplify is TRUE, then apply returns an array of dimension c(n, dim(X)[MARGIN])

Whichever way you bind it, your desc_n function returns something of length 2, so you get 2 rows in the apply-simplified output.

Why apply() returns a transposed xts matrix?

That's what apply is documented to do. From ?apply:

Value:

 If each call to ‘FUN’ returns a vector of length ‘n’, then ‘apply’
returns an array of dimension ‘c(n, dim(X)[MARGIN])’ if ‘n > 1’.

In your case, 'n'=48 (because you're looping over rows), so apply will return an array of dimension c(48, 7429).

Also note that myxts.2 is not an xts object. It's a regular array. You have a couple options:

  1. transpose the results of apply before re-creating your xts object:

    data(sample_matrix)
    myxts <- as.xts(sample_matrix)
    dim(myxts) # [1] 180 4
    myxts.2 <- apply(myxts, 1 , identity)
    dim(myxts.2) # [1] 4 180
    myxts.2 <- xts(t(apply(myxts, 1 , identity)), index(myxts))
    dim(myxts.2) # [1] 180 4
  2. Vectorize your function so it operates on all the rows of an xts
    object and returns an xts object. Then you don't have to worry
    about apply at all.

Finally, please start providing reproducible examples. It's not that hard and it makes it a lot easier for people to help. I've provided an example above and I hope you can use it in your following questions.

How do I transpose a tibble() in R

As Sotos has mentioned it, you just need to re-declare your matrix as a tibble:

as_tibble(cbind(nms = names(df), t(df)))

R - apply / mapply - Transpose is Required

Just have a look at the documentation (?apply)

If each call to FUN returns a vector of length n, then apply returns an array of dimension c(n, dim(X)[MARGIN]) if n > 1.

In other words: The number of rows of the resulting matrix is given by the length of the vectors in your function to be applied.



Related Topics



Leave a reply



Submit