применение функции сортировки в r для каждых четырех строк возвращает отсортированный кадр данных, но без расширенного выбора, другие столбцы не сортируются соответственно - PullRequest
0 голосов
/ 04 июля 2019

Мне нужно, чтобы каждые четыре строки сортировались по 4-му столбцу, отдельно от следующих четырех строк, сделал функцию:

for (i in seq(1,nrow(data_frame), by=4)) { 

    data_frame[i:(i+3),4] <- sort(data_frame[i:(i+3),4], decreasing=TRUE) }

проблема в том, что сортируется только 4-й столбец, но сохраняются соответствующие строки.

от

x y z userID
-1 1 2 5      1
-2 1 1 2      2
-3 0 0 5      5
-6 1 2 5      3

-4 1 1 2      6
-5 0 0 5      4
-4 1 1 2      1
-5 0 0 5      5

до -

x y z userID
-1 1 2 5      5
-2 1 1 2      3
-3 0 0 5      2
-6 1 2 5      1

-4 1 1 2      6
-5 0 0 5      5
-4 1 1 2      4
-5 0 0 5      1

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

С tidyverse мы можем использовать %/% для создания столбца группировки с %/% и использовать его для sort 'userID'

library(tidyverse)
df1 %>%
    group_by(grp = (row_number()-1) %/% 4 + 1) %>% 
    #or use
    #group_by(grp = cumsum(rep(c(TRUE, FALSE, FALSE, FALSE), length.out = n()))) %>%
    mutate(userID = sort(userID, decreasing = TRUE))
# A tibble: 8 x 5
# Groups:   grp [2]
#      x     y     z userID   grp
#  <int> <int> <int>  <int> <dbl>
#1     1     2     5      5     1
#2     1     1     2      3     1
#3     0     0     5      2     1
#4     1     2     5      1     1
#5     1     1     2      6     2
#6     0     0     5      5     2
#7     1     1     2      4     2
#8     0     0     5      1     2

Или с помощью base R с ave

with(df1, ave(userID, (seq_along(userID)-1) %/% 4 + 1, 
         FUN = function(x) sort(x, decreasing = TRUE)))
#[1] 5 3 2 1 6 5 4 1

данные

df1 <- structure(list(x = c(1L, 1L, 0L, 1L, 1L, 0L, 1L, 0L), y = c(2L, 
1L, 0L, 2L, 1L, 0L, 1L, 0L), z = c(5L, 2L, 5L, 5L, 2L, 5L, 2L, 
5L), userID = c(1L, 2L, 5L, 3L, 6L, 4L, 1L, 5L)), row.names = c(NA, 
-8L), class = "data.frame")
0 голосов
/ 04 июля 2019

В базе R мы можем split каждые 4 строки, order четвертый столбец и возвращать обновленный кадр данных обратно.

df[] <- do.call(rbind, lapply(split(df, gl(nrow(df)/4, 4)), 
                  function(p) p[order(p[[4]], decreasing = TRUE), ]))

df
#  x y z userID
#1 0 0 5      5
#2 1 2 5      3
#3 1 1 2      2
#4 1 2 5      1
#5 1 1 2      6
#6 0 0 5      5
#7 0 0 5      4
#8 1 1 2      1

tidyverse подход с использованием той же логики будет

library(tidyverse)
df %>%
  group_split(gl(n()/4, 4), keep = FALSE) %>%
  map_dfr(. %>% arrange(desc(userID)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...