Вот мой фрейм данных:

ID  Dryweight   root    network number
1074    81.95   0.087877389 2.842105263 465
1074    57.11   0.08651187  1.7 367
1074    87.14   0.0840022   2.153846154 450
1074    75.52   0.085173817 2.068965517 532
1125    73.7    0.089987396 1.909090909 724
1125    75.41   0.089343593 1.628571429 516
1125    48.36   0.084626918 2.571428571 515
1125    66.33   0.078110279 1.567567568 503
1125    59.72   0.085949892 3   452

И что я хочу сделать, так это получить новый кадр данных после удаления максимальных и минимальных значений всех столбцов по группе (здесь должен быть основан на идентификаторе). Я пытался использовать «агрегат», но не смог.

1
wuqiannian 3 Дек 2019 в 19:19
Что вы имеете в виду, когда хотите удалить значения? Вы хотите удалить всю строку? Вы хотите установить значение на отсутствующее? Каков желаемый результат для этого примера ввода. Как выглядела ваша попытка aggregate?
 – 
MrFlick
3 Дек 2019 в 19:28
На самом деле, я просто хочу удалить 2 значения (максимальные и минимальные значения) для каждого столбца по идентификатору, а не удалять всю строку.
 – 
wuqiannian
3 Дек 2019 в 19:32
Опять же, что означает «удалить», установить NA? установить на 0? А если есть связи?
 – 
MrFlick
3 Дек 2019 в 19:34
1
Для групп, состоящих только из 2 участников, вы получите пустой фрейм данных, если удалите минимальные и максимальные значения во всех столбцах... этого вы ожидаете?
 – 
ThomasIsCoding
3 Дек 2019 в 19:37
Нет, просто отбросьте максимальное и минимальное значения.
 – 
wuqiannian
3 Дек 2019 в 19:39

1 ответ

Удаление min или max для id но будет работать только в том случае, если у каждого из них одинаковое количество совпадений для min и max и есть оставшиеся< /эм>.

split на ID и обработайте list с помощью lapply. Перейдите к каждой строке, используя apply и подмножество, проверяя min и max.

tt <- do.call(rbind, lapply(split(x, x[1])
  , function(y) cbind(ID=y[-1:-2,1], apply(y[-1], 2
     , function(z) z[z>min(z) & z<max(z)]))))
tt
#       ID Dryweight       root  network number
#[1,] 1074     81.95 0.08651187 2.153846    465
#[2,] 1074     75.52 0.08517382 2.068966    450
#[3,] 1125     73.70 0.08934359 1.909091    516
#[4,] 1125     66.33 0.08462692 1.628571    515
#[5,] 1125     59.72 0.08594989 2.571429    503

Или установить min или max для id на NA, что будет работать в любом случае.

cbind(x[1], do.call(rbind, lapply(split(x[-1], x[1])
  , function(y) apply(y, 2
     , function(z) z[c(NA, TRUE)[1 + (z>min(z) & z<max(z))]]))))
#    ID Dryweight       root  network number
#1 1074     81.95         NA       NA    465
#2 1074        NA 0.08651187       NA     NA
#3 1074        NA         NA 2.153846    450
#4 1074     75.52 0.08517382 2.068966     NA
#5 1125     73.70         NA 1.909091     NA
#6 1125        NA 0.08934359 1.628571    516
#7 1125        NA 0.08462692 2.571429    515
#8 1125     66.33         NA       NA    503
#9 1125     59.72 0.08594989       NA     NA

Данных:

x <- structure(list(ID = c(1074L, 1074L, 1074L, 1074L, 1125L, 1125L, 
1125L, 1125L, 1125L), Dryweight = c(81.95, 57.11, 87.14, 75.52, 
73.7, 75.41, 48.36, 66.33, 59.72), root = c(0.087877389, 0.08651187, 
0.0840022, 0.085173817, 0.089987396, 0.089343593, 0.084626918, 
0.078110279, 0.085949892), network = c(2.842105263, 1.7, 2.153846154, 
2.068965517, 1.909090909, 1.628571429, 2.571428571, 1.567567568, 
3), number = c(465L, 367L, 450L, 532L, 724L, 516L, 515L, 503L, 
452L)), class = "data.frame", row.names = c(NA, -9L))
0
GKi 3 Дек 2019 в 20:11
В любом случае спасибо, но я хочу новый фрейм данных без минимума и максимума, а не для выбора или извлечения.
 – 
wuqiannian
3 Дек 2019 в 19:53
Вы получаете новый data.frame без min и max.
 – 
GKi
3 Дек 2019 в 19:57
Извините, я не очень хорошо понял y[-1:-2,1]. Что означает здесь «-» или «-1:-2»? И я предполагаю, что последняя «1» относится, вероятно, к первому столбцу.
 – 
wuqiannian
3 Дек 2019 в 22:35
 – 
GKi
4 Дек 2019 в 10:20