arrange_() multiple columns with descending order
We can paste
'desc' as a string to evaluate it.
myCol1 <- paste0("desc(", "x)")
df1 %>%
arrange_(.dots = c("grp", myCol1))
# grp x
#1 1 6.16
#2 1 3.39
#3 1 2.82
#4 2 9.17
#5 2 4.35
Or with 'myCol'
df1 %>%
arrange_(.dots = c("grp", paste0("desc(", myCol, ")")))
Or use lazyeval
library(lazyeval)
df1 %>%
arrange_(.dots = c("grp", interp(~ desc(n1), n1 = as.name(myCol))))
# grp x
#1 1 6.16
#2 1 3.39
#3 1 2.82
#4 2 9.17
#5 2 4.35
By using "desc(myCol)"
, it is a single string and the value of the 'myCol' is not evaluated.
Update
Or another option is parse_expr
(from rlang
) and evaluate with !!
df1 %>%
arrange(grp, !! rlang::parse_expr(myCol1))
#grp x
#1 1 6.16
#2 1 3.39
#3 1 2.82
#4 2 9.17
#5 2 4.35
Or using the original string in the OP's post. Convert the string to symbol (sym
), evaluate (!!
) and arrange it in descending (desc
) order
myCol <- "x"
df1 %>%
arrange(grp, desc(!! rlang::sym(myCol)))
# grp x
#1 1 6.16
#2 1 3.39
#3 1 2.82
#4 2 9.17
#5 2 4.35
How to sort a Pandas DataFrame with multiple columns, some in ascending order and others descending order?
The DataFrame.sort_values
method can handle this very easily. Just use the ascending
argument and provide a list of boolean values.
import pandas as pd
my_df = pd.DataFrame({'col1':['a','a','a','a','b','b','b','b','c','c','c','c'],
'col2':[1,1,2,2,1,1,2,2,1,1,2,2],
'col3':[1,2,1,2,1,2,1,2,1,2,1,2]})
my_df = my_df.sort_values(by=['col1','col2','col3'],
ascending=[False, False, True])
Note that the list provided in the ascending
argument must have the same length as the one provided in the by
argument.
Descending sorting in numpy by several columns
Use numpy.lexsort
to sort on multiple columns at the same time.
arr = np.array([
[150, 8],
[105, 20],
[90, 100],
[101, 12],
[110, 80],
[105, 100],
])
order = np.lexsort([arr[:, 1], arr[:, 0]])[::-1]
arr[order]
yields:
array([[150, 8],
[110, 80],
[105, 100],
[105, 20],
[101, 12],
[ 90, 100]])
Sort (order) data frame rows by multiple columns
You can use the order()
function directly without resorting to add-on tools -- see this simpler answer which uses a trick right from the top of the example(order)
code:
R> dd[with(dd, order(-z, b)), ]
b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1
Edit some 2+ years later: It was just asked how to do this by column index. The answer is to simply pass the desired sorting column(s) to the order()
function:
R> dd[order(-dd[,4], dd[,1]), ]
b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1
R>
rather than using the name of the column (and with()
for easier/more direct access).
Set Ascending Descending for each column when sorting by multiple columns
From the docs:
reverse is a boolean value. If set to
True
, then the list elements are sorted as if each comparison were reversed.
So what you want instead is something like:
d.sort(key=lambda x: (x[0], -x[1]))
If x[1]
is not a number, try:
d.sort(key=lambda x: x[1], reverse=True)
d.sort(key=lambda x: x[0])
R: sort by multiple columns with a specific order in each column (not ascending)
We can create factor columns and specify the level to arrange the column. The last mutate_if
is optional, which is just converting the factor back to character.
library(dplyr)
dat2 <- dat %>%
mutate(A = factor(A, level = c("yellow", "green", "red")),
B = factor(B, c("X", "Z", "Y"))) %>%
arrange(A, B, desc(C)) %>%
mutate_if(is.factor, as.character)
dat2
# A B C D E
# 1 yellow X 0.8 bbbb 126
# 2 yellow X 0.5 cccc 324
# 3 yellow X 0.4 zzzz 222
# 4 yellow Z 0.6 dddd 333
# 5 yellow Y 0.2 dddd 222
# 6 green X 0.3 cccc 111
# 7 green Y 0.1 aaaa 123
# 8 red X 0.8 aaaa 111
DATA
dat <- read.table(text = " A B C D E
1 red X 0.8 aaaa 111
2 yellow Y 0.2 dddd 222
3 green X 0.3 cccc 111
4 yellow Z 0.6 dddd 333
5 green Y 0.1 aaaa 123
6 yellow X 0.5 cccc 324
7 yellow X 0.4 zzzz 222
8 yellow X 0.8 bbbb 126",
header = TRUE, stringsAsFactors = FALSE)
SQL multiple column ordering
ORDER BY column1 DESC, column2
This sorts everything by column1
(descending) first, and then by column2
(ascending, which is the default) whenever the column1
fields for two or more rows are equal.
Arranging summarized NAs in descending order after calculating them in each column in tidyverse
I think the issue is caused by the summarise function returning a single column ("col_name : value") instead of two columns ("col_name" and "variable"). One potential solution is to use the pivot_longer() tidyverse function to split the output into two columns, e.g.
library(tidyverse)
data(airquality)
dat1 <- airquality
dat1 %>%
summarise(across(everything(), ~ sum(is.na(.)))) %>%
pivot_longer(cols = everything(), names_to = "names", values_to = "values") %>%
arrange(desc(values))
#> # A tibble: 6 x 2
#> names values
#> <chr> <int>
#> 1 Ozone 37
#> 2 Solar.R 7
#> 3 Wind 0
#> 4 Temp 0
#> 5 Month 0
#> 6 Day 0
Created on 2021-07-21 by the reprex package (v2.0.0)
Related Topics
Rcpp Function Calling Another Rcpp Function
R Subsetting a Data Frame into Multiple Data Frames Based on Multiple Column Values
Setting Default Number of Decimal Places for Printing
Ggplot2 Multiline Title, Different Indentations
Test for Na and Select Values Based on Result
Custom Fill Color in Ggvis (And Other Options)
Rcmdr Launch Error in Yosemite (Os X 10.10)
Use a Factor Column in "By" and Do Not Drop Empty Factors
R/Quantmod: Multiple Charts All Using the Same Y-Axis
Check If Value Is in Data Frame
Sorting of Categorical Variables in Ggplot
Plot Decision Boundaries with Ggplot2
Logistic Regression with Robust Clustered Standard Errors in R