2016-11-18 5 views
2

После набора данных воспроизводятСравните каждую строку в каждой группе

group <- c(1,1,2,2,3,3) 
parameter <- c("A","B","A","B","A","B") 
values <- c(10,20,20,5,30,50) 
df <- data.frame(group,parameter,values) 

group parameter values 
    1   A  10 
    1   B  20 
    2   A  20 
    2   B  5 
    3   A  30 
    3   B  50 

Я хочу проверить в каждой группе A> B (сохранить этот результат в четвертом столбце для всей группы)

Если да -> TRUE, если нет -> FALSE

Нового Df:

group parameter values status 
    1   A  10  FALSE 
    1   B  20  FALSE 
    2   A  20  TRUE 
    2   B  5  TRUE 
    3   A  30  FALSE 
    3   B  50  FALSE 

подхода

с (ДФ, пр (значения, группа, FUN = функция (х)))

Я не могу думать, что будет код внутри функции. Может кто-то пожалуйста, помогите мне

Обновлено: Статус должен быть ранжированы в соответствии столбце значений (от высшего к низшему) в группе

group parameter values status 
    1   A  10  2 
    1   B  20  1 
    2   A  20  1 
    2   B  5  2 
    3   A  30  2 
    3   B  50  1 
+0

Существует всегда точно 1 А и 1 значение B в каждой группе? –

+0

Да ровно 1 А и 1 В в каждой группе –

ответ

3

Мы можем попытаться с data.table. Преобразуйте «data.frame» в «data.frame» в «data.table» (setDT(df)), сгруппированные по «группе», сравните «значения», где «параметр» равен «A» с «B» и присвойте (:=) статус

library(data.table) 
setDT(df)[, status := values[parameter=="A"]>values[parameter=="B"], by = group] 
df 
# group parameter values status 
#1:  1   A  10 FALSE 
#2:  1   B  20 FALSE 
#3:  2   A  20 TRUE 
#4:  2   B  5 TRUE 
#5:  3   A  30 FALSE 
#6:  3   B  50 FALSE 

и для rank, используйте frank на „ценности“ после того, как группировка по «группе.

setDT(df)[, status:= frank(-values), group] 
df 
# group parameter values status 
#1:  1   A  10  2 
#2:  1   B  20  1 
#3:  2   A  20  1 
#4:  2   B  5  2 
#5:  3   A  30  2 
#6:  3   B  50  1 

Или с ave, мы можем сравнивать первое значение с помощью второго (при условии, что параметр «» заказан, а также только два элемента в «группы»

df$status <- with(df, as.logical(ave(values, group, FUN = function(x) x[1] > x[2]))) 

Или другой вариант заключается в order наборе данных по первым столбцам (в случае, если он не упорядочен), подмножество «значений» путем повторного использования логического индекса, сравнивать и реплицировать каждый из логических значений val ЕЭС по 2.

df1 <- df[do.call(order, df[1:2]), ] 
rep(df1$values[c(TRUE, FALSE)] > df1$values[c(FALSE, TRUE)], each = 2) 
+0

Эй, это круто. Предположим, хочу ли я ранжировать параметр, является ли решение в тех же строках? –

+0

@ Хардик Можете ли вы обновить свой пост с ожидаемым рангом – akrun

1

Существует также tidyverse решение с использованием dplyr:

library(dplyr) 

    df %>% 
     group_by(group) %>% 
     mutate(status = ifelse(values[parameter == "A"] > values[parameter == "B"], TRUE, FALSE), 
      rank = min_rank(-values)) 

Source: local data frame [6 x 5] 
Groups: group [3] 

    group parameter values status rank 
    (dbl) (fctr) (dbl) (lgl) (int) 
1  1   A  10 FALSE  2 
2  1   B  20 FALSE  1 
3  2   A  20 TRUE  1 
4  2   B  5 TRUE  2 
5  3   A  30 FALSE  2 
6  3   B  50 FALSE  1 
Смежные вопросы