How can I export multidimensional matrix from julia in Excel? - multidimensional-array

I have a multiple dimensional matrix in my result for example x[I, j, k, t]. How can I export it from Julia in Excel?
For example I have this matrix in Julia. I coded a location inventory vehicle routing model in Julia. That is the optimum routing matrix. I want to export it in Excel.
`xx
x: 4 dimensions:
[1,:,:,:]
[1,1,:,:]
[1,1,1,:]
[1,1,1,1] = 0.0
[1,1,1,2] = 0.0
[1,1,1,3] = 0.0
[1,1,2,:]
[1,1,2,1] = 0.0
[1,1,2,2] = 0.0
[1,1,2,3] = 0.0
[1,1,3,:]
[1,1,3,1] = 0.0
[1,1,3,2] = 0.0
[1,1,3,3] = 0.0
[1,2,:,:]
[1,2,1,:]
[1,2,1,1] = -0.0
[1,2,1,2] = 0.0
[1,2,1,3] = 0.0
[1,2,2,:]
[1,2,2,1] = 0.0
[1,2,2,2] = 0.0
[1,2,2,3] = 0.0
[1,2,3,:]
[1,2,3,1] = 0.0
[1,2,3,2] = 0.0
[1,2,3,3] = 0.0
[1,3,:,:]
[1,3,1,:]
[1,3,1,1] = -0.0
[1,3,1,2] = 0.0
[1,3,1,3] = 0.0
[1,3,2,:]
[1,3,2,1] = 0.0
[1,3,2,2] = 0.0
[1,3,2,3] = -0.0
[1,3,3,:]
[1,3,3,1] = 0.0
[1,3,3,2] = 0.0
[1,3,3,3] = 0.0
[1,4,:,:]
[1,4,1,:]
[1,4,1,1] = -0.0
[1,4,1,2] = -0.0
[1,4,1,3] = -0.0
[1,4,2,:]
[1,4,2,1] = -0.0
[1,4,2,2] = -0.0
[1,4,2,3] = -0.0
[1,4,3,:]
[1,4,3,1] = 0.0
[1,4,3,2] = 0.0
[1,4,3,3] = 0.0
[1,5,:,:]
[1,5,1,:]
[1,5,1,1] = -0.0
[1,5,1,2] = -0.0
[1,5,1,3] = -0.0
[1,5,2,:]
[1,5,2,1] = -0.0
[1,5,2,2] = -0.0
[1,5,2,3] = 0.0
[1,5,3,:]
[1,5,3,1] = -0.0
[1,5,3,2] = 0.0
[1,5,3,3] = 0.0
[1,6,:,:]
[1,6,1,:]
[1,6,1,1] = -0.0
[1,6,1,2] = -0.0
[1,6,1,3] = -0.0
[1,6,2,:]
[1,6,2,1] = -0.0
[1,6,2,2] = -0.0
[1,6,2,3] = 1.0
[1,6,3,:]
[1,6,3,1] = 1.0
[1,6,3,2] = 1.0
[1,6,3,3] = -0.0
[2,:,:,:]
[2,1,:,:]
[2,1,1,:]
[2,1,1,1] = 0.0
[2,1,1,2] = 0.0
[2,1,1,3] = 0.0
[2,1,2,:]
[2,1,2,1] = 0.0
[2,1,2,2] = 0.0
[2,1,2,3] = 1.0
[2,1,3,:]
[2,1,3,1] = 1.0
[2,1,3,2] = 1.0
[2,1,3,3] = 0.0
[2,2,:,:]
[2,2,1,:]
[2,2,1,1] = 0.0
[2,2,1,2] = 0.0
[2,2,1,3] = 0.0
[2,2,2,:]
[2,2,2,1] = 0.0
[2,2,2,2] = 0.0
[2,2,2,3] = 0.0
[2,2,3,:]
[2,2,3,1] = 0.0
[2,2,3,2] = 0.0
[2,2,3,3] = 0.0
[2,3,:,:]
[2,3,1,:]
[2,3,1,1] = 0.0
[2,3,1,2] = 0.0
[2,3,1,3] = -0.0
[2,3,2,:]
[2,3,2,1] = 0.0
[2,3,2,2] = 0.0
[2,3,2,3] = 0.0
[2,3,3,:]
[2,3,3,1] = 0.0
[2,3,3,2] = 0.0
[2,3,3,3] = 0.0
[2,4,:,:]
[2,4,1,:]
[2,4,1,1] = -0.0
[2,4,1,2] = -0.0
[2,4,1,3] = -0.0
[2,4,2,:]
[2,4,2,1] = -0.0
[2,4,2,2] = -0.0
[2,4,2,3] = -0.0
[2,4,3,:]
[2,4,3,1] = 0.0
[2,4,3,2] = -0.0
[2,4,3,3] = -0.0
[2,5,:,:]
[2,5,1,:]
[2,5,1,1] = 0.0
[2,5,1,2] = -0.0
[2,5,1,3] = -0.0
[2,5,2,:]
[2,5,2,1] = 0.0
[2,5,2,2] = -0.0
[2,5,2,3] = -0.0
[2,5,3,:]
[2,5,3,1] = 0.0
[2,5,3,2] = -0.0
[2,5,3,3] = -0.0
[2,6,:,:]
[2,6,1,:]
[2,6,1,1] = -0.0
[2,6,1,2] = -0.0
[2,6,1,3] = -0.0
[2,6,2,:]
[2,6,2,1] = -0.0
[2,6,2,2] = -0.0
[2,6,2,3] = -0.0
[2,6,3,:]
[2,6,3,1] = -0.0
[2,6,3,2] = -0.0
[2,6,3,3] = -0.0
[3,:,:,:]
[3,1,:,:]
[3,1,1,:]
[3,1,1,1] = 0.0
[3,1,1,2] = 0.0
[3,1,1,3] = 0.0
[3,1,2,:]
[3,1,2,1] = -0.0
[3,1,2,2] = 0.0
[3,1,2,3] = 0.0
[3,1,3,:]
[3,1,3,1] = -0.0
[3,1,3,2] = -0.0
[3,1,3,3] = 0.0
[3,2,:,:]
[3,2,1,:]
[3,2,1,1] = 0.0
[3,2,1,2] = -0.0
[3,2,1,3] = 0.0
[3,2,2,:]
[3,2,2,1] = 0.0
[3,2,2,2] = -0.0
[3,2,2,3] = 1.0
[3,2,3,:]
[3,2,3,1] = 1.0
[3,2,3,2] = 0.9999999999999996
[3,2,3,3] = 0.0
[3,3,:,:]
[3,3,1,:]
[3,3,1,1] = 0.0
[3,3,1,2] = 0.0
[3,3,1,3] = 0.0
[3,3,2,:]
[3,3,2,1] = 0.0
[3,3,2,2] = 0.0
[3,3,2,3] = 0.0
[3,3,3,:]
[3,3,3,1] = 0.0
[3,3,3,2] = 0.0
[3,3,3,3] = 0.0
[3,4,:,:]
[3,4,1,:]
[3,4,1,1] = 0.0
[3,4,1,2] = -0.0
[3,4,1,3] = -0.0
[3,4,2,:]
[3,4,2,1] = -0.0
[3,4,2,2] = -0.0
[3,4,2,3] = 0.0
[3,4,3,:]
[3,4,3,1] = 0.0
[3,4,3,2] = -0.0
[3,4,3,3] = -0.0
[3,5,:,:]
[3,5,1,:]
[3,5,1,1] = 0.0
[3,5,1,2] = -0.0
[3,5,1,3] = 0.0
[3,5,2,:]
[3,5,2,1] = 0.0
[3,5,2,2] = -0.0
[3,5,2,3] = -0.0
[3,5,3,:]
[3,5,3,1] = -0.0
[3,5,3,2] = -0.0
[3,5,3,3] = -0.0
[3,6,:,:]
[3,6,1,:]
[3,6,1,1] = -0.0
[3,6,1,2] = -0.0
[3,6,1,3] = -0.0
[3,6,2,:]
[3,6,2,1] = -0.0
[3,6,2,2] = -0.0
[3,6,2,3] = -0.0
[3,6,3,:]
[3,6,3,1] = -0.0
[3,6,3,2] = -0.0
[3,6,3,3] = -0.0
[4,:,:,:]
[4,1,:,:]
[4,1,1,:]
[4,1,1,1] = -0.0
[4,1,1,2] = 0.0
[4,1,1,3] = 0.0
[4,1,2,:]
[4,1,2,1] = -0.0
[4,1,2,2] = 0.0
[4,1,2,3] = -0.0
[4,1,3,:]
[4,1,3,1] = -0.0
[4,1,3,2] = -0.0
[4,1,3,3] = -0.0
[4,2,:,:]
[4,2,1,:]
[4,2,1,1] = -0.0
[4,2,1,2] = -0.0
[4,2,1,3] = -0.0
[4,2,2,:]
[4,2,2,1] = -0.0
[4,2,2,2] = -0.0
[4,2,2,3] = 0.0
[4,2,3,:]
[4,2,3,1] = -0.0
[4,2,3,2] = 0.0
[4,2,3,3] = -0.0
[4,3,:,:]
[4,3,1,:]
[4,3,1,1] = 0.0
[4,3,1,2] = 0.0
[4,3,1,3] = -0.0
[4,3,2,:]
[4,3,2,1] = 0.0
[4,3,2,2] = 0.0
[4,3,2,3] = 1.0
[4,3,3,:]
[4,3,3,1] = 1.0
[4,3,3,2] = 0.9999999999999996
[4,3,3,3] = 0.0
[4,4,:,:]
[4,4,1,:]
[4,4,1,1] = 0.0
[4,4,1,2] = 0.0
[4,4,1,3] = 0.0
[4,4,2,:]
[4,4,2,1] = 0.0
[4,4,2,2] = 0.0
[4,4,2,3] = 0.0
[4,4,3,:]
[4,4,3,1] = 0.0
[4,4,3,2] = 0.0
[4,4,3,3] = 0.0
[4,5,:,:]
[4,5,1,:]
[4,5,1,1] = -0.0
[4,5,1,2] = -0.0
[4,5,1,3] = 0.0
[4,5,2,:]
[4,5,2,1] = 0.0
[4,5,2,2] = 0.0
[4,5,2,3] = -0.0
[4,5,3,:]
[4,5,3,1] = -0.0
[4,5,3,2] = -0.0
[4,5,3,3] = 0.0
[4,6,:,:]
[4,6,1,:]
[4,6,1,1] = -0.0
[4,6,1,2] = -0.0
[4,6,1,3] = -0.0
[4,6,2,:]
[4,6,2,1] = -0.0
[4,6,2,2] = -0.0
[4,6,2,3] = -0.0
[4,6,3,:]
[4,6,3,1] = -0.0
[4,6,3,2] = -0.0
[4,6,3,3] = -0.0
[5,:,:,:]
[5,1,:,:]
[5,1,1,:]
[5,1,1,1] = -0.0
[5,1,1,2] = 0.0
[5,1,1,3] = 0.0
[5,1,2,:]
[5,1,2,1] = -0.0
[5,1,2,2] = 0.0
[5,1,2,3] = -0.0
[5,1,3,:]
[5,1,3,1] = 0.0
[5,1,3,2] = 0.0
[5,1,3,3] = -0.0
[5,2,:,:]
[5,2,1,:]
[5,2,1,1] = 0.0
[5,2,1,2] = -0.0
[5,2,1,3] = -0.0
[5,2,2,:]
[5,2,2,1] = -0.0
[5,2,2,2] = -0.0
[5,2,2,3] = 0.0
[5,2,3,:]
[5,2,3,1] = 0.0
[5,2,3,2] = 0.0
[5,2,3,3] = -0.0
[5,3,:,:]
[5,3,1,:]
[5,3,1,1] = 0.0
[5,3,1,2] = -0.0
[5,3,1,3] = 0.0
[5,3,2,:]
[5,3,2,1] = 0.0
[5,3,2,2] = -0.0
[5,3,2,3] = 0.0
[5,3,3,:]
[5,3,3,1] = 0.0
[5,3,3,2] = -0.0
[5,3,3,3] = -0.0
[5,4,:,:]
[5,4,1,:]
[5,4,1,1] = 0.0
[5,4,1,2] = 0.0
[5,4,1,3] = 0.0
[5,4,2,:]
[5,4,2,1] = 0.0
[5,4,2,2] = -0.0
[5,4,2,3] = 1.0
[5,4,3,:]
[5,4,3,1] = 1.0
[5,4,3,2] = 0.9999999999999996
[5,4,3,3] = 0.0
[5,5,:,:]
[5,5,1,:]
[5,5,1,1] = 0.0
[5,5,1,2] = 0.0
[5,5,1,3] = 0.0
[5,5,2,:]
[5,5,2,1] = 0.0
[5,5,2,2] = 0.0
[5,5,2,3] = 0.0
[5,5,3,:]
[5,5,3,1] = 0.0
[5,5,3,2] = 0.0
[5,5,3,3] = 0.0
[5,6,:,:]
[5,6,1,:]
[5,6,1,1] = -0.0
[5,6,1,2] = -0.0
[5,6,1,3] = 0.0
[5,6,2,:]
[5,6,2,1] = 0.0
[5,6,2,2] = 0.0
[5,6,2,3] = -0.0
[5,6,3,:]
[5,6,3,1] = 0.0
[5,6,3,2] = -0.0
[5,6,3,3] = -0.0
[6,:,:,:]
[6,1,:,:]
[6,1,1,:]
[6,1,1,1] = -0.0
[6,1,1,2] = 0.0
[6,1,1,3] = -0.0
[6,1,2,:]
[6,1,2,1] = -0.0
[6,1,2,2] = -0.0
[6,1,2,3] = -0.0
[6,1,3,:]
[6,1,3,1] = -0.0
[6,1,3,2] = -0.0
[6,1,3,3] = -0.0
[6,2,:,:]
[6,2,1,:]
[6,2,1,1] = -0.0
[6,2,1,2] = -0.0
[6,2,1,3] = -0.0
[6,2,2,:]
[6,2,2,1] = -0.0
[6,2,2,2] = -0.0
[6,2,2,3] = 0.0
[6,2,3,:]
[6,2,3,1] = -0.0
[6,2,3,2] = -0.0
[6,2,3,3] = -0.0
[6,3,:,:]
[6,3,1,:]
[6,3,1,1] = -0.0
[6,3,1,2] = -0.0
[6,3,1,3] = -0.0
[6,3,2,:]
[6,3,2,1] = -0.0
[6,3,2,2] = -0.0
[6,3,2,3] = -0.0
[6,3,3,:]
[6,3,3,1] = -0.0
[6,3,3,2] = -0.0
[6,3,3,3] = -0.0
[6,4,:,:]
[6,4,1,:]
[6,4,1,1] = -0.0
[6,4,1,2] = -0.0
[6,4,1,3] = -0.0
[6,4,2,:]
[6,4,2,1] = -0.0
[6,4,2,2] = -0.0
[6,4,2,3] = -0.0
[6,4,3,:]
[6,4,3,1] = -0.0
[6,4,3,2] = 0.0
[6,4,3,3] = -0.0
[6,5,:,:]
[6,5,1,:]
[6,5,1,1] = 0.0
[6,5,1,2] = 0.0
[6,5,1,3] = -0.0
[6,5,2,:]
[6,5,2,1] = -0.0
[6,5,2,2] = -0.0
[6,5,2,3] = 1.0
[6,5,3,:]
[6,5,3,1] = 1.0
[6,5,3,2] = 0.9999999999999996
[6,5,3,3] = 0.0
[6,6,:,:]
[6,6,1,:]
[6,6,1,1] = 0.0
[6,6,1,2] = 0.0
[6,6,1,3] = 0.0
[6,6,2,:]
[6,6,2,1] = 0.0
[6,6,2,2] = 0.0
[6,6,2,3] = 0.0
[6,6,3,:]
[6,6,3,1] = 0.0
[6,6,3,2] = 0.0
[6,6,3,3] = 0
.0`

You can write it to a .csv file which will be easily imported in an Excel sheet.
Working code for Julia 1.1.0 and JuMP 0.19.0
x = [0.0 for _ in 1:6, _ in 1:6, _ in 1:3, _ in 1:3]
using CSV
using DataFrames
function arr_to_csv(x, outputstring)
df = DataFrame(i = Int[], j = Int[], k = Int[], t = Int[], x = Float64[])
sizes = size(x)
for i in 1:sizes[1]
for j in 1:sizes[2]
for k in 1:sizes[3]
for t in 1:sizes[4]
push!(df, (i, j, k, t, x[i,j,k,t]))
end
end
end
end
df |> CSV.write(outputstring, header = ["i", "j", "k", "t", "value"])
end
arr_to_csv(x, "./4dim-x.csv")
Replace x with your matrix

Related

Rescale positive and negative numbers into [0, 1] and [-1, 0]

I have a data frame like this:
Input_df <- data.frame(Enl_ID = c("INTS121410", "INTS175899", "INTS171428", "INTS156006", "INTS196136", "INTS114771" ), `CN4244` = c(5, 0, -0.4, -0.6, 10, 2), `CN4249` = c(10, -4, -10, -2, 6, 0), `CN4250` = c(40, 10, 4, -10, 0, 4))
I'm trying to rescale the positive values between 0-1 and negative values between 0 to -1 so the output would be like
Output_df <- data.frame(Enl_ID = c("INTS121410", "INTS175899", "INTS171428", "INTS156006", "INTS196136", "INTS114771" ), `CN4244` = c(0.5, 0, -0.66, -1, 1, 0.2), `CN4249` = c(1, -0.4, -1, -0.2, 0.6, 0), `CN4250` = c(1, 0.25, 0.1, -1, 0, 0.1))
I found few examples like at stackoverflow but this is only for single-column and my file run into almost 2000 column so it is not possible to do it manually on every column.
Any idea how to do it?
Any help would be appreciated. Thanks in advance
You could use
library(dplyr)
Input_df %>%
mutate(across(starts_with("CN"), ~.x / max(abs(.x))))
This returns
Enl_ID CN4244 CN4249 CN4250
1 INTS121410 0.50 1.0 1.00
2 INTS175899 0.00 -0.4 0.25
3 INTS171428 -0.04 -1.0 0.10
4 INTS156006 -0.06 -0.2 -0.25
5 INTS196136 1.00 0.6 0.00
6 INTS114771 0.20 0.0 0.10
Or, if you want different rescaling factors for positive and negative values:
Input_df %>%
mutate(across(starts_with("CN"),
~case_when(.x >= 0 ~ .x / max(.x),
TRUE ~ - .x / min(.x))))
This returns
Enl_ID CN4244 CN4249 CN4250
1 INTS121410 0.5000000 1.0 1.00
2 INTS175899 0.0000000 -0.4 0.25
3 INTS171428 -0.6666667 -1.0 0.10
4 INTS156006 -1.0000000 -0.2 -1.00
5 INTS196136 1.0000000 0.6 0.00
6 INTS114771 0.2000000 0.0 0.10

Assigning specific color to a range of values in heatmap using pheamap

I want to make a heatmap using pheatmap where if anything is between -1 to -0.5 it should be darkgreen and anything between -0.5 to -0.10 as lightgreen and anything between -0.10 to 0 as white. Similarly 0 to 0.10 as white, 0.10 to 0.5 as light purple and anything between 0.5 to 1 as purple. I also don't want to scale my data and no clustering. I have this code so far in R:
0.85 0.63 0.61 0.60 0.53 0.23 0.20 0.15 0.12 0.08 0.04 -0.05 -0.08 -0.19 -0.34 -0.56 -0.78
0.75 0.54 0.51 0.50 0.45 0.41 0.35 0.12 0.08 0.04 -0.01 -0.07 -0.15 -0.45 -0.51 -0.57 -0.68
df <- read.table("test.txt", header = FALSE, sep = "\t")
pheatmap(as.matrix(df),
scale="none",
cluster_rows = FALSE,
cluster_cols = FALSE,
annotation_names_col = FALSE,
show_colnames= FALSE,
color = colorRampPalette(colors = c("darkgreen","white","purple"))(200),
main = "A3SS",
border_color = NA,
fontsize_row=10
)
How can I use breaks in pheatmap to achieve my goal?
You have to set the breaks and build the color palette correctly - this should do the job if you really want 200 colors (if not see the next section):
library(pheatmap)
# dummy data
df <- data.table::fread("0.85 0.63 0.61 0.60 0.53 0.23 0.20 0.15 0.12 0.08 0.04 -0.05 -0.08 -0.19 -0.34 -0.56 -0.78
0.75 0.54 0.51 0.50 0.45 0.41 0.35 0.12 0.08 0.04 -0.01 -0.07 -0.15 -0.45 -0.51 -0.57 -0.68")
# make the color pallete
clrsp <- colorRampPalette(c("darkgreen", "white", "purple"))
clrs <- clrsp(200)
breaks1 <- seq(-1, 1, length.out = 200)
pheatmap(as.matrix(df),
scale="none",
cluster_rows = FALSE,
cluster_cols = FALSE,
annotation_names_col = FALSE,
show_colnames= FALSE,
color = clrs,
main = "A3SS",
breaks = breaks1,
fontsize_row=10)
in case that you want just to work with five color and cut exactly at the informed values, one option to source from a already made pallet of the RColorBrewer packages:
breaks2 <- c(-1, -0.5, -0.1, 0.1, 0.5, 1)
pheatmap(as.matrix(df),
scale="none",
cluster_rows = FALSE,
cluster_cols = FALSE,
annotation_names_col = FALSE,
show_colnames= FALSE,
color = rev(RColorBrewer::brewer.pal(5, name = "PiYG")),
main = "A3SS",
breaks = breaks2,
fontsize_row=10)
Alternatively you can inform color in a vector but there is no explicite light purple from text anyhow you could you hex color codes to be more precise then just "light"/"dark":
pheatmap(as.matrix(df),
scale="none",
cluster_rows = FALSE,
cluster_cols = FALSE,
annotation_names_col = FALSE,
show_colnames= FALSE,
color = c("darkgreen","lightgreen","white","darkorchid1","purple"),
main = "A3SS",
breaks = breaks2,
fontsize_row=10)

R Make scatter plots (ggplot) from columns based on attributes from rows

I have the following type of table :
df0 <- read.table(text = 'Sample Method Mg Al Ca Ti
Sa A 5.5 2.2 33 0.2
Sb A 4.2 1.2 44 0.1
Sc A 1.1 0.5 25 0.3
Sd A 3.3 1.3 31 0.5
Se A 6.2 0.2 55 0.6
Sa B 5.2 2 35 0.25
Sb B 4.6 1.3 48 0.1
Sc B 1.6 0.8 22 0.32
Sd B 3.1 1.6 29 0.4
Se B 6.8 0.3 51 0.7
Sa C 5.6 2.5 30 0.2
Sb C 4.1 1.2 41 0.15
Sc C 1 0.6 22 0.4
Sd C 3.2 1.5 30 0.5
Se C 6.8 0.1 51 0.65', header = T, stringsAsFactors = F)
Which include chemical compositions. I would like to use the Method A as a reference (X-axis) and to make automated scatter plots with the data from Method B, C in Y (with linear trend). With a reference line of 1:1 which would correspond to a perfect match.
In other words, I would like to produce plots like that :
I think a solution could start from transforming the data frame into:
df <- read.table(text = 'Sample Mg_A Al_A Ca_A Ti_A Mg_B Al_B Ca_B Ti_B Mg_C Al_C Ca_C Ti_C
Sa 5.5 2.2 33 0.2 5.2 2 35 0.25 5.6 2.5 30 0.2
Sb 4.2 1.2 44 0.1 4.6 1.3 48 0.1 4.1 1.2 41 0.15
Sc 1.1 0.5 25 0.3 1.6 0.8 22 0.32 1 0.6 22 0.4
Sd 3.3 1.3 31 0.5 3.1 1.6 29 0.4 3.2 1.5 30 0.5
Se 6.2 0.2 55 0.6 6.8 0.3 51 0.7 6.8 0.1 51 0.65
', header = T, stringsAsFactors = F)
But I don't know how to go further.
Any help would be appreciated.
Best, Anne-Christine
You can use the following code
library(tidyverse)
df0 %>%
pivot_wider(names_from = Method, values_from = c(Mg, Al, Ca, Ti)) %>%
pivot_longer(cols = -Sample) %>% #wide to long data format
separate(name, c("key","number"), sep = "_") %>%
group_by(number) %>% #Group the vaules according to number
mutate(row = row_number()) %>% #For creating unique IDs
pivot_wider(names_from = number, values_from = value) %>%
ggplot() +
geom_point(aes(x=A, y=B, color = "A vs B")) +
geom_point(aes(x=A, y=C, color = "A vs C")) +
geom_abline(slope=1, intercept=0) +
geom_smooth(aes(x=A, y=B, color = "A vs B"), method=lm, se=FALSE, fullrange=TRUE)+
geom_smooth(aes(x=A, y=C, color = "A vs C"), method=lm, se=FALSE, fullrange=TRUE)+
facet_wrap(key~., scales = "free")+
theme_bw()+
ylab("B or C") +
xlab("A")
Data
df0 = structure(list(Sample = c("Sa", "Sb", "Sc", "Sd", "Se", "Sa",
"Sb", "Sc", "Sd", "Se", "Sa", "Sb", "Sc", "Sd", "Se"), Method = c("A",
"A", "A", "A", "A", "B", "B", "B", "B", "B", "C", "C", "C", "C",
"C"), Mg = c(5.5, 4.2, 1.1, 3.3, 6.2, 5.2, 4.6, 1.6, 3.1, 6.8,
5.6, 4.1, 1, 3.2, 6.8), Al = c(2.2, 1.2, 0.5, 1.3, 0.2, 2, 1.3,
0.8, 1.6, 0.3, 2.5, 1.2, 0.6, 1.5, 0.1), Ca = c(33L, 44L, 25L,
31L, 55L, 35L, 48L, 22L, 29L, 51L, 30L, 41L, 22L, 30L, 51L),
Ti = c(0.2, 0.1, 0.3, 0.5, 0.6, 0.25, 0.1, 0.32, 0.4, 0.7,
0.2, 0.15, 0.4, 0.5, 0.65)), class = "data.frame", row.names = c(NA,
-15L))

Split Default Without Sorting It By Column Names

On the following data I am running split.default() in R. The problem is that the separated sub data.frames() in the list are getting into sorted based on column name.
I don't want this to occur and want to preserve the column name sequence as that is the original data. Is there an approach that I can follow to do so? Please suggest.
Input Data
data <- structure(list(`B-DIODE` = c(1.2, 0.4), `B-DIODE` = c(1.3, 0.6
), `A-DIODE` = c(1.4, 0.8), `A-ACC1` = c(1.5, 1), `A-ACC2` = c(1.6,
1.2), `A-ANA0` = c(1.7, 1.4), `A-ANA1` = c(1.8, 1.6), `A-BRICKID` = c(1.9,
1.8), `A-CC0` = c(2L, 2L), `A-CC1` = c(2.1, 2.2), `A-DIGDN` = c(2.2,
2.4), `A-DIGDP` = c(2.3, 2.6), `A-DN1` = c(2.4, 2.8), `A-DN2` = c(2.5,
3), `A-DP1` = c(2.6, 3.2), `A-DP2` = c(2.7, 3.4), `A-SCL` = c(2.8,
3.6), `A-SDA` = c(2.9, 3.8), `A-USB0DN` = 3:4, `A-USB0DP` = c(3.1,
4.2), `A-USB1DN` = c(3.2, 4.4), `A-USB1DP` = c(3.3, 4.6), `A-ACC1` = c(3.4,
4.8), `A-ACC2` = c(3.5, 5), `A-ANA0` = c(3.6, 5.2), `A-ANA1` = c(3.7,
5.4), `A-BRICKID` = c(3.8, 5.6), `A-CC0` = c(3.9, 5.8), `A-CC1` = c(4L,
6L), `A-DIGDN` = c(4.1, 6.2), `A-DIGDP` = c(4.2, 6.4), `A-DN1` = c(4.3,
6.6), `A-DN2` = c(4.4, 6.8), `A-DP1` = c(4.5, 7), `A-DP2` = c(4.6,
7.2), `A-SCL` = c(4.7, 7.4), `A-SDA` = c(4.8, 7.6), `A-USB0DN` = c(4.9,
7.8), `A-USB0DP` = c(5L, 8L), `A-USB1DN` = c(5.1, 8.2), `A-USB1DP` = c(5.2,
8.4), `A-NA` = c(5.3, 8.6), `A-ACC2PWRLKG_0v4` = c(5.4, 8.8),
`A-ACC2PWRLKG_0v4` = c(5.5, 9), `A-P_IN_Leak` = c(5.6, 9.2
)), class = "data.frame", row.names = c(NA, -2L))
Code
split.default(data, sub("-.*", "", names(data)))
Output
$`A`
A-DIODE A-ACC1 A-ACC2 A-ANA0 A-ANA1 A-BRICKID A-CC0 A-CC1 A-DIGDN A-DIGDP A-DN1 A-DN2 A-DP1 A-DP2 A-SCL A-SDA A-USB0DN A-USB0DP A-USB1DN A-USB1DP
1 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3 3.1 3.2 3.3
2 0.8 1.0 1.2 1.4 1.6 1.8 2 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4 4.2 4.4 4.6
A-ACC1.1 A-ACC2.1 A-ANA0.1 A-ANA1.1 A-BRICKID.1 A-CC0.1 A-CC1.1 A-DIGDN.1 A-DIGDP.1 A-DN1.1 A-DN2.1 A-DP1.1 A-DP2.1 A-SCL.1 A-SDA.1 A-USB0DN.1
1 3.4 3.5 3.6 3.7 3.8 3.9 4 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9
2 4.8 5.0 5.2 5.4 5.6 5.8 6 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8
A-USB0DP.1 A-USB1DN.1 A-USB1DP.1 A-NA A-ACC2PWRLKG_0v4 A-ACC2PWRLKG_0v4.1 A-P_IN_Leak
1 5 5.1 5.2 5.3 5.4 5.5 5.6
2 8 8.2 8.4 8.6 8.8 9.0 9.2
$B
B-DIODE B-DIODE.1
1 1.2 1.3
2 0.4 0.6
In the above output I want the $B to appear first and then $A as that's the sequence that Input Data followed.
One option is to convert the names to factor and set the levels as needed
new_name <- sub("-.*", "", names(data))
split.default(data, factor(new_name, levels = unique(new_name)))
#$B
# B-DIODE B-DIODE.1
#1 1.2 1.3
#2 0.4 0.6
#$A
# A-DIODE A-ACC1 A-ACC2 A-ANA0 ....
#1 1.4 1.5 1.6 1.7 ....
#2 0.8 1.0 1.2 1.4 ....
by specifying levels as unique(new_name) we can ensure that the list will be split based on their occurrence in the dataframe and not alphabetically.
As #thelatemail suggests we can also avoid converting names to factor variable by reordering the list based on unique new_name
split.default(data, new_name)[unique(new_name)]
Another option is to create the group indices for splitting using rle
rl <- rle(sub("-.*", "", names(data)))
split.default(data, rep(1:length(rl), rl$length))
#$`1`
# B-DIODE B-DIODE.1
#1 1.2 1.3
#2 0.4 0.6
#
#$`2`
# A-DIODE A-ACC1 A-ACC2 A-ANA0 A-ANA1 A-BRICKID A-CC0 A-CC1 A-DIGDN A-DIGDP
#1 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3
#2 0.8 1.0 1.2 1.4 1.6 1.8 2 2.2 2.4 2.6
# A-DN1 A-DN2 A-DP1 A-DP2 A-SCL A-SDA A-USB0DN A-USB0DP A-USB1DN A-USB1DP
#1 2.4 2.5 2.6 2.7 2.8 2.9 3 3.1 3.2 3.3
#2 2.8 3.0 3.2 3.4 3.6 3.8 4 4.2 4.4 4.6
# A-ACC1.1 A-ACC2.1 A-ANA0.1 A-ANA1.1 A-BRICKID.1 A-CC0.1 A-CC1.1 A-DIGDN.1
#1 3.4 3.5 3.6 3.7 3.8 3.9 4 4.1
#2 4.8 5.0 5.2 5.4 5.6 5.8 6 6.2
# A-DIGDP.1 A-DN1.1 A-DN2.1 A-DP1.1 A-DP2.1 A-SCL.1 A-SDA.1 A-USB0DN.1
#1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9
#2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8
# A-USB0DP.1 A-USB1DN.1 A-USB1DP.1 A-NA A-ACC2PWRLKG_0v4 A-ACC2PWRLKG_0v4.1
#1 5 5.1 5.2 5.3 5.4 5.5
#2 8 8.2 8.4 8.6 8.8 9.0
# A-P_IN_Leak
#1 5.6
#2 9.2

Convert to negative a number

In data like this:
data.frame (com = c("col1","em"), stock1 = c(2.6, 0), aim = c(0,3.10))
How is it possible to add a minus to all rows of row with com "em"
Example of expected result:
data.frame (com = c("col1","em"), stock1 = c(2.6, 0), aim = c(0,-3.10))
com stock1 aim
1 col1 2.6 0.0
2 em 0.0 -3.1
Using ifelse:
df1 <- data.frame (com = c("col1","em"), stock1 = c(2.6, 0), aim = c(0,3.10))
df1$aim <- ifelse(df1$com == "em", -df1$aim, df1$aim)
df1
com stock1 aim
1 col1 2.6 0.0
2 em 0.0 -3.1
How does this work?
xy <- data.frame (com = c("col1","em"), stock1 = c(2.6, 0), aim = c(0,3.10))
find.com <- -which(names(xy) == "com")
xy[xy$com == "em", find.com] <- -xy[xy$com == "em", find.com]
xy
com stock1 aim
1 col1 2.6 0.0
2 em 0.0 -3.1

Resources