How to Reorder Data.Table Columns (Without Copying)

How to reorder data.table columns (without copying)

Use setcolorder():

library(data.table)
x <- data.table(a = 1:3, b = 3:1, c = runif(3))
x
# a b c
# [1,] 1 3 0.2880365
# [2,] 2 2 0.7785115
# [3,] 3 1 0.3297416
setcolorder(x, c("c", "b", "a"))
x
# c b a
# [1,] 0.2880365 3 1
# [2,] 0.7785115 2 2
# [3,] 0.3297416 1 3

From ?setcolorder:

In data.table parlance, all set* functions change their input by reference. That is, no copy is made at all, other than temporary working memory, which is as large as one column.

so should be pretty efficient. See ?setcolorder for details.

How do I reorder data.table columns?

Use setcolorder:

> library(data.table)
> dt <- data.table(a=1:3,b=4:6)
> setcolorder(dt, c("b", "a"))
> dt
b a
1: 4 1
2: 5 2
3: 6 3

Reorder data.table with variable columns

Managed to find the solution after toying around more with setcolorder:

setcolorder(dt, c(vector, "percentage", colnames(dt)[!(colnames(dt) %in% vector) & !(colnames(dt) == "percentage")]))

Reorder certain columns by a pattern within a data.table R

This should work. In future, please provide a minimal, reproducible example as it makes question much easier to answer (and therefore more likely to attract answers!)

## I use the stringr package
### I find it easier to understand
require(stringr)
#> Loading required package: stringr

test <- data.frame(
Week = c("week1", "week2", "week3"),
PSRS_Germany = c("some", "data", "idk"),
PSRS_Israel = c("this", "is", "data"),
AR_Germany = c("yes", "it's", "data"),
AR_Israel = c("hmm", "look", "values"),
totalPSRS = c("yes", "yeah", "hmm"),
totalAR = c("foo", "bar", "BIFF!")
)

test
#> Week PSRS_Germany PSRS_Israel AR_Germany AR_Israel totalPSRS totalAR
#> 1 week1 some this yes hmm yes foo
#> 2 week2 data is it's look yeah bar
#> 3 week3 idk data data values hmm BIFF!

## Get just the names we want to rearrange
testNames <- names(test)
testNames <- testNames[str_detect(testNames, "_")]

## Rearragne those names
orderedNames <-
testNames[
order(str_extract(testNames, "_.+(?=$)"), # order by what's between string start and '_'
str_extract(testNames, "(?<=^).+_")) # _then_ by what's between '_' and string end
]

## Index using newly rearranged names
test[,c("Week",
orderedNames,
"totalPSRS", "totalAR")]
#> Week AR_Germany PSRS_Germany AR_Israel PSRS_Israel totalPSRS totalAR
#> 1 week1 yes some hmm this yes foo
#> 2 week2 it's data look is yeah bar
#> 3 week3 data idk values data hmm BIFF!

Created on 2021-09-13 by the reprex package (v2.0.1)

Reordering multiple columns by fill with count and legend reorder

One option would be to make use of a helper column

  1. arrange your data by generation and N
  2. create a helper column. I simply paste generation and device_type together.
  3. Set the levels of the helper column in the order of the dataset using e.g. forcats::fct_inorder
  4. Map the helper column on the group aes
library(dplyr)
library(forcats)
library(ggplot2)

dy2 <- dy2 %>%
arrange(generation, N) %>%
mutate(
device_type2 = paste(generation, device_type, sep = "_"),
device_type2 = fct_inorder(device_type2)
)

ggplot(dy2, aes(x = generation, y = N, fill = device_type, group = device_type2)) +
geom_bar(position = position_dodge(), alpha = 0.85, stat = "identity") +
geom_text(position = position_dodge(0.9), aes(y = N + 0.8, label = N), size = 3, show.legend = FALSE) +
scale_fill_manual(
name = NULL,
values = c("blue", "black", "red", "green3", "cyan4", "purple"),
breaks = c(
"Accessories", "Aspiration_catheter", "Guidewire",
"Microcatheter", "Sheath", "Stentretriever"
)
) +
theme_classic()

Sample Image

R How to find and reorder columns in one table according to column order in another table (tables contain diff number of columns)

Install and load dplyr package for select function. Other functions used match, order, is.na, which and operator %in%.

  install.packages("plyr")
install.packages("dplyr")
library(plyr)
library(dplyr)

table1 = data.frame(rbind(c(rep(c(TRUE,FALSE), 3)), c(rep(TRUE, 4), rep(FALSE, 2))))
dim(table1)
names(table1) <- letters[1:6]

table2 = data.frame(rbind(c(rep(c(TRUE,FALSE), 2)), c(rep(TRUE, 3), rep(FALSE, 1))))
dim(table2)
names(table2) <- letters[7:4]

target <- as.vector(names(table2))
t <- select(table1, which(names(table1) %in% target))
gg <- match (target,names(t))
gg <- gg[!is.na(gg)]
Result <- t[,order(gg)]
Result

r - Need a workaround for copying a data.table in a reference class

You should use data.table::copy instead of the default reference class copy method:

library(data.table)

Example <- setRefClass("Example",
fields = list(
data1 = "data.table"
),

method = list(
tryToCopyData1 = function(){
data_temp <- data.table::copy(data1)
}
)
)

example <- Example$new()

example$data1 <- data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)

example$tryToCopyData1()


Related Topics



Leave a reply



Submit