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.
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:
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 4Vectorize 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
aboutapply
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.
R apply result is inconsistent
With a little help from friends, I came up with this simpler, base-R solution:
df$id<-unlist(apply(df,1,function(x)
ifelse(x["first"]=="none",0, which(as.integer(x["first"])==as.integer(x[2:10])))))
See the answers there for an explanation of why apply
was problematic -- briefly, it transformed all your data to character, but then padded it in a way that made the comparisons fail.
On a related note, when you read.csv
, you might want to add stringsAsFactors=FALSE
to avoid making the first
column a factor.
Transpose result of combn in R
I would simply use t()
to transpose it
c2 <- t(combn(mylist, 2))
How to transpose a list of data frames?
Here is an approach using lapply()
.
# generate some data frames
set.seed(102134)
id <- 1:5
aList <- lapply(id,function(x){
data.frame(matrix(runif(50),nrow=10,ncol=5))
})
# transpose and remove first 2 rows
transposeList <- lapply(aList,function(x){
t(x)[-c(1,2),]
})
# print first transposed data frame
transposeList[[1]]
..and the output, noting that rows representing variables X1
and X2
in the original data frame have been omitted from the data frame we print:
> # print first transposed data frame
> transposeList[[1]]
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
X3 0.1128006 0.5884873 0.8532827 0.5957727 0.6995990 0.09765447 0.69149804
X4 0.1239681 0.7624771 0.9756067 0.1251610 0.4954070 0.92652298 0.04800376
X5 0.3698154 0.6789413 0.9660355 0.6613972 0.5099627 0.97766102 0.97139575
[,8] [,9] [,10]
X3 0.7731442 0.03916568 0.8787288
X4 0.3829343 0.41939016 0.9668663
X5 0.8865407 0.63437436 0.6774895
>
An important subtlety in this answer is the line of code t(x)[-c(1,2),]
in the anonymous function within lapply()
. Since the result of t(x)
is an object, we can immediately use the [
form of the extract operator to remove the first two rows.
Diff function transposes matrix when used with apply over rows
To elaborate on the "transpose effect" of apply
:
According to ?apply
, apply
applies a function to the row vectors (MARGIN = 1
) or column vectors (MARGIN = 2
) of an array (e.g. a matrix
) and returns
an array of dimension ‘c(n, dim(X)[MARGIN])’ if ‘n > 1’
where n is the length of the vector returned by an individual call of the function to either the row or column vector.
So in your case dim(m)
is 2 10
(i.e. a 2x10
matrix) and MARGIN = 1
, so the array dimension of the return object is 9 2
, which means a 9x2
matrix (as diff
returns a vector of length n=9
).
You can see the same "transpose effect" when you do
apply(m, 1, c)
# [,1] [,2]
# [1,] 1 2
# [2,] 3 4
# [3,] 5 6
# [4,] 7 8
# [5,] 9 10
# [6,] 11 12
# [7,] 13 14
# [8,] 15 16
# [9,] 17 18
#[10,] 19 20
R transposing numeric data.frame results in character variables
After transposing it, convert the columns to numeric
with type.convert
out <- as.data.frame(t(sampleDF), stringsAsFactors = FALSE)
out[] <- lapply(out, type.convert, as.is = TRUE)
row.names(out) <- NULL
out
# V1 V2 V3 V4
#1 1 2 3 String
#2 1 2 3 4
#3 5 6 7 8
str(out)
#'data.frame': 3 obs. of 4 variables:
# $ V1: int 1 1 5
# $ V2: int 2 2 6
# $ V3: int 3 3 7
# $ V4: chr "String" "4" "8"
Or rbind
the first column converted to respective 'types' with the transposed other columns
rbind(lapply(sampleDF[,1], type.convert, as.is = TRUE),
as.data.frame(t(sampleDF[2:3])))
NOTE: The first method would be more efficient
Or another approach would be to paste
the values together in each column and then read it again
read.table(text=paste(sapply(sampleDF, paste, collapse=" "),
collapse="\n"), header = FALSE, stringsAsFactors = FALSE)
# V1 V2 V3 V4
#1 1 2 3 String
#2 1 2 3 4
#3 5 6 7 8
Or we can convert the 'data.frame' to 'data.matrix' which changes the character
elements to NA
, use the is.na
to find the index of elements that are NA for replacing with the original string values
m1 <- data.matrix(sampleDF)
out <- as.data.frame(t(m1))
out[is.na(out)] <- sampleDF[is.na(m1)]
Or another option is type_convert
from readr
library(dplyr)
library(readr)
sampleDF %>%
t %>%
as_data_frame %>%
type_convert
# A tibble: 3 x 4
# V1 V2 V3 V4
# <int> <int> <int> <chr>
#1 1 2 3 String
#2 1 2 3 4
#3 5 6 7 8
Related Topics
R Shiny Loop to Display Multiple Plots
Generally Disable Dimension Dropping for Matrices
How to Automatically Load Data in an R Package
How to Change Name of Factor Levels
Contrast Between Label and Background: Determine If Color Is Light or Dark
R Sum Every K Columns in Matrix
Extract Last Non-Missing Value in Row with Data.Table
Repeat the Re-Sampling Function for 1000 Times? Using Lapply
How to Create a Bar and Line Plot with R Dygraphs
Converting to Date in a Character Column That Contains Two Date Formats
R Group By, Counting Non-Na Values
"Object Not Found" Error Within a User Defined Function, Eval() Function