закажите два столбца, условно выберите значения, затем запустите cumsum frequency
Мои данные выглядят так
a b c
1 1 0
1 2 8
2 1 0
2 2 2
3 1 3
3 2 3
4 1 7
4 2 4
5 1 3
5 2 5
6 1 1
6 2 8
7 1 1
7 2 2
Я хочу отсортировать столбцы a и c так, чтобы каждая четная строка в столбце c была наибольшим числом для каждой пары в столбце A. Затем я хочу взять эти значения и сохранить их в новом объекте. Это должно выглядеть примерно так.
a c b
1 8 2
2 2 2
3 3 2
4 7 1
5 5 2
6 8 2
7 2 2
4 ответа:
С помощью пакета
data.table
Вы можете сортировать данные по ссылке с помощьюsetorder
илиsetkey
(без необходимости создавать копии с помощью функции<-
)Тогда вы можете достичь своей цели различными простыми способами, напримерlibrary(data.table) setorder(setDT(df), a, c)[] # a b c # 1: 1 1 0 # 2: 1 2 8 # 3: 2 1 0 # 4: 2 2 2 # 5: 3 1 3 # 6: 3 2 3 # 7: 4 1 7 # 8: 4 2 4 # 9: 5 1 3 # 10: 5 2 5 # 11: 6 1 1 # 12: 6 2 8 # 13: 7 1 1 # 14: 7 2 2
df[duplicated(a)] # a b c # 1: 1 2 8 # 2: 2 2 2 # 3: 3 2 3 # 4: 4 2 4 # 5: 5 2 5 # 6: 6 2 8 # 7: 7 2 2
Или, может быть,
df[, tail(.SD, 1), a] # a b c # 1: 1 2 8 # 2: 2 2 2 # 3: 3 2 3 # 4: 4 2 4 # 5: 5 2 5 # 6: 6 2 8 # 7: 7 2 2
Или
P.S. Если вы хотите изменить порядок столбцов , вы также можете сделать это с помощью ссылки, используя функциюdf[, .SD[2], a] # a b c # 1: 1 2 8 # 2: 2 2 2 # 3: 3 2 3 # 4: 4 2 4 # 5: 5 2 5 # 6: 6 2 8 # 7: 7 2 2
setcolorder
, например,setcolorder(df, c("a", "c", "b"))
Вы можете использовать такой подход:
dat[order(dat$a, dat$c), ][c(FALSE, TRUE), ] # a b c # 2 1 2 8 # 4 2 2 2 # 6 3 2 3 # 7 4 1 7 # 10 5 2 5 # 12 6 2 8 # 14 7 2 2
Альтернативный подход с
dplyr
:library(dplyr) dat %>% arrange(a, c) %>% filter(duplicated(a))
Вот один из способов. Если ваши данные уже расположены так, как df, я бы сделал
slice(group_by(mydf, a), 2)
, используяdplyr
. Но я не уверен, что это так. Я создал образец и сделал следующее. Когда есть ничья вc
, Вы, кажется, также рассматриваетеb
; Вы взяли ряд с max(b). Так что, я думаю, это, вероятно, один из способов пойти.library(dplyr) foo <- data.frame(a = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5), b = c(3, 5, 5, 6, 7, 1, 7, 3, 9, 2), c = c(4, 0, 2, 6, 7, 7, 5, 2, 8, 1)) # a b c #1 1 3 4 #2 1 5 0 #3 2 5 2 #4 2 6 6 #5 3 7 7 #6 3 1 7 #7 4 7 5 #8 4 3 2 #9 5 9 8 #10 5 2 1 group_by(arrange(foo, a, c, b), a) %>% slice(2) # a b c #1 1 3 4 #2 2 6 6 #3 3 7 7 #4 4 7 5 #5 5 9 8
Если я правильно понимаю вашу проблему, это решение должно соответствовать вашим потребностям:
### Sample data a <- rep(1:7, each = 2) b <- rep(1:2, length(a)/2) c <- c(0, 8, 0, 2, 3, 3, 7, 4, 3, 5, 1, 8, 1, 2) abc <- cbind(a, b, c) ### Identify unique values of 'a' unique_a <- unique(abc[, 1]) # Loop over all unique values of 'a' t(sapply(unique_a, function(i) { # Subset data by current unique entry tmp_abc <- abc[which(abc[, 1] == i), ] # Extract corresponding values of 'c' tmp_val_c <- tmp_abc[, 3] # If all values of 'c' are equal, take the 2nd entry (i.e. row) if (tmp_val_c[1] == tmp_val_c[2]) { id_max <- 2 # Else, identify the row with the maximum value of 'c' } else { id_max <- which.max(tmp_abc[, 3]) } # Return row holding maximum value of 'c' return(tmp_abc[id_max, c(1, 3, 2)]) }))
Соответствующее возвращаемое значение выглядит следующим образом:
a c b [1,] 1 8 2 [2,] 2 2 2 [3,] 3 3 2 [4,] 4 7 1 [5,] 5 5 2 [6,] 6 8 2 [7,] 7 2 2