R: вычислить медианы столбцов, сгруппировав идентификаторы

Продолжая мой предыдущий сообщение, теперь я хочу сгруппировать по идентификатору (только для столбца 3 ) и вычислите медиану столбца (Point_B), а затем вычтите медианное значение из каждого значения в столбце (Point_B) в соответствующую группу. NA все равно должны быть возвращены.

Примечание. Я хочу, чтобы группировка идентификаторов применялась только к столбцу Point_B, а не к Point_A, поскольку я хочу вычислить медиану всего столбца Point_A и вычесть ее со значениями в Point_A.

Например

ID <- c("A","A","A","B","B","B","C","C","C") 
Point_A <- c(1,2,NA,1,2,3,1,2,NA) 
Point_B <- c(1,2,3,NA,NA,1,1,1,3)

df <- data.frame(ID,Point_A ,Point_B)


+----+---------+---------+
| ID | Point_A | Point_B |
+----+---------+---------+
| A  | 1       | 1       |
| A  | 2       | 2       |
| A  | NA      | 3       |
| B  | 1       | NA      |
| B  | 2       | NA      |
| B  | 3       | 1       |
| C  | 1       | 1       |
| C  | 2       | 1       |
| C  | NA      | 3       |
+----+---------+---------+

Решение, представленное в моем предыдущем посте, вычисляет медианы без группировки по идентификатору. Вот

library(dplyr)
 df %>%
     mutate_each(funs(median=.-median(., na.rm=TRUE)), -ID)

Желаемый результат

+----+---------+---------+
| ID | Point_A | Point_B |
+----+---------+---------+
| A  | -1      | -1      |
| A  | 0       | 0       |
| A  | NA      | 1       |
| B  | -1      | NA      |
| B  | 0       | NA      |
| B  | 1       | 0       |
| C  | -1      | 0       |
| C  | 0       | 0       |
| C  | NA      | 2       |
+----+---------+---------+

Как получить значения в Column3 с группировкой по ID?


person Sharath    schedule 08.05.2015    source источник


Ответы (1)


Я думаю, вам понадобится group_by (следуя предложению @docendodiscimus):

demed <- function(x) x-median(x,na.rm=TRUE)

df %>% 
  mutate_each(funs(demed),Point_A) %>%
  group_by(ID) %>%  
  mutate_each(funs(demed),Point_B)

давать

  ID Point_A Point_B
1  A      -1      -1
2  A       0       0
3  A      NA       1
4  B      -1      NA
5  B       0      NA
6  B       1       0
7  C      -1       0
8  C       0       0
9  C      NA       2

Я предпочитаю аналогичный код data.table. Его синтаксис требует написания имен переменных несколько раз, но в нем гораздо меньше круглых скобок:

require(data.table)
DT <- data.table(df)

DT[,Point_A:=demed(Point_A)
][,Point_B:=demed(Point_B)
,by=ID]
person Frank    schedule 08.05.2015
comment
Фрэнк, спасибо за предложение, но мой желаемый результат немного отличается. Я показал это выше. Мне нужно взять медианы и вычесть каждое значение в столбце. Не могли бы вы проверить это? - person Sharath; 09.05.2015
comment
Спасибо за отредактированный код. Но столбец Point_A кажется неизменным. Можем ли мы сделать это вместе или мне нужно сделать это отдельно для каждого столбца Point_A и Point_B? - person Sharath; 09.05.2015
comment
Я хочу сгруппировать медианы только для столбца Point_B. Пожалуйста, проверьте мой желаемый результат. - person Sharath; 09.05.2015
comment
@Sharath Вам нужно будет определить свою медианную функцию перед конвейером, но это выполняет свою работу с довольно хорошим синтаксисом. - person Frank; 09.05.2015
comment
Выдающаяся работа. Я получил результат с вашим новым редактированием. Большое спасибо. Я применил его к большему набору данных, и он работает как шарм. - person Sharath; 09.05.2015
comment
ИМО, подход dplyr должен быть df %>% mutate(Point_A = demed(Point_A)) %>% group_by(ID) %>% mutate(Point_B = demed(Point_B)) - person talat; 10.05.2015
comment
@docendodiscimus Что мне больше всего нравится в dplyr (что я заметил до сих пор), так это анонимные функции с .. Они облегчают чтение (например, мы сделали Point_A2?... лучше присмотритесь) и избегают опечаток (например, случайного ввода Point_a). Но да, ваш способ, вероятно, идиоматичен. - person Frank; 10.05.2015
comment
Если вы предпочитаете использовать mutate_each в этом случае, я бы сделал небольшую поправку, чтобы сделать его чище: mutate_each(funs(demed),Point_A) - person talat; 10.05.2015