Я пытаюсь создать ранжированную таблицу, в которой мне нужно отсортировать каждую пару столбцов по второму столбцу в каждой паре. Первый столбец в каждой паре должен иметь соответствующее значение. Как я могу сделать это кратким/простым способом?
df <- data.frame(
State1 = c("Ak", "Al", "Az"),
Value1 = c(1, 10, 30),
State2 = c("Ak", "Al", "Az"),
Value2 = c(45, 3, 20))
Я хочу, чтобы конечный результат выглядел так:
State1 Value1 State2 Value2
Az 30 Ak 45
Al 10 Az 20
Ak 1 Al 3
Обычно элементы в каждой строке фрейма данных семантически связаны, поэтому я не уверен, что есть простой способ. library(dplyr); bind_cols( df |> select(1:2) |> arrange(-Value1), df |> select(3:4) |> arrange(-Value2))
Хаком было бы сначала разделить фреймы данных на два, изменить порядок их числовых столбцов, а затем объединить их обратно в один фрейм данных, например:
library(dplyr)
df <- data.frame(
State1 = c("Ak", "Al", "Az"),
Value1 = c(1, 10, 30),
State2 = c("Ak", "Al", "Az"),
Value2 = c(45, 3, 20))
df1 <- df[,c("State1","Value1")]
df2 <- df[,c("State2","Value2")]
df1 <- df1 |>
arrange(desc(Value1))
df2 <- df2 |>
arrange(desc(Value2))
df_merge <- cbind(df1,df2)
df_merge
State1 Value1 State2 Value2
1 Az 30 Ak 45
2 Al 10 Az 20
3 Ak 1 Al 3
Надеюсь это поможет!
Вот решение в base
без необходимости создания «вспомогательных» переменных; По сути, я нарезаю фрейм данных для каждой пары, затем сортирую каждый фрагмент на основе второго столбца, то есть значения #, а затем объединяю отсортированные кадры данных вместе.
lapply(seq(1, ncol(df), by=2), \(i) df[i:min((i+1), ncol(df))]) |>
lapply(\(d) d[order(d[,2], decreasing = TRUE), ]) |>
cbind.data.frame()
#> State1 Value1 State2 Value2
#> 3 Az 30 Ak 45
#> 2 Al 10 Az 20
#> 1 Ak 1 Al 3
Решение base
:
df |>
split.default(ceiling(seq_along(df) / 2)) |> # slice after every second column
lapply(\(x) x[order(-x[, 2]),]) |> # order by the second column
unname() |> # drop list names
data.frame() # convert back to data frame
# State1 Value1 State2 Value2
#3 Az 30 Ak 45
#2 Al 10 Az 20
#1 Ak 1 Al 3
library(purrr)
library(tibble)
split.default(df, rep(1:2, each = ncol(df) %/% 2)) |>
map_dfc(\(x) enframe(sort(deframe(x), decreasing = T))) |>
set_names(names(df))
Это выполняет итерацию по двум столбцам за раз, превращает этот фрейм данных в именованный вектор, где State
— это имя, а Value
— значение, сортирует этот вектор в порядке убывания, преобразует его обратно в фрейм данных, а затем объединяет их столбцы: мудрый.
Используйте sort_by
из основания R > 4,4.
unname(split.default(df, gsub("\\D", "", names(df)))) |>
lapply(\(y)sort_by(y, -y[[2]]))|>
cbind.data.frame()
State1 Value1 State2 Value2
3 Az 30 Ak 45
2 Al 10 Az 20
1 Ak 1 Al 3
Это выглядит как два отдельных фрейма данных. Почему они вместе?