2016-08-08 2 views
1

Я хочу взять каждое второе измерение из data.frame в соответствии с переменной группировки. Например, в data.frame Input, возьмите каждый второй Sample для каждого ID:Как я могу удалить каждую n-ю строку из кадра данных в R, в соответствии с переменной группировки?

head(Input, 10) 
      Sample X  ID 
    15918  1 -1.326285 EABE_D5 
    15919  2 -1.315783 EABE_D5 
    15920  3 -1.313245 EABE_D5 
    15921  4 -1.304670 EABE_D5 
    15922  5 -1.309060 EABE_D5 
    15923  1 -1.292412 EABE_D4 
    15924  2 -1.294728 EABE_D4 
    15925  3 -1.282006 EABE_D4 
    15926  4 -1.287245 EABE_D4 
    15927  5 -1.278444 EABE_D4 

и создать новый data.frame имени Output:

Output 
     Sample X  ID 
15919  2 -1.315783 EABE_D5 
15921  4 -1.304670 EABE_D5 
15924  2 -1.294728 EABE_D4 
15926  4 -1.287245 EABE_D4 

Возможно ли это? Спасибо.

+0

Спасибо, но это приводит к data.frame с каждым 'Sample' равным 2. Тем не менее, я хочу, чтобы каждый второй образец соответствовал моему ожидаемому результату. – user2716568

+1

как насчет 'Input [Input $ Sample %% 2 == 0,]'. Это занимает только четные образцы. – symbolrush

ответ

2

Мы можем использовать dplyr. После того, как группировка по 'ID', мы slice строки на основе четного индекса, возвращенного seq

library(dplyr) 
Input %>% 
    group_by(ID) %>% 
    slice(seq(2, n(), by =2)) 
# Sample   X  ID 
# <int>  <dbl> <chr> 
#1  2 -1.294728 EABE_D4 
#2  4 -1.287245 EABE_D4 
#3  2 -1.315783 EABE_D5 
#4  4 -1.304670 EABE_D5 

Или мы можем использовать data.table для повышения эффективности

library(data.table) 
setDT(Input)[Input[, .I[seq(2, .N, by = 2)], by = ID]$V1] 

Или с ave из base R, мы группируем по 'ID', применяем оператор modulo %% с y как 2, конвертируем в логический путем отрицания (!), и с этим логическим вектором мы подмножаем строки.

Input[with(Input, !ave(Sample, ID, FUN = function(x) x %%2)),] 
#  Sample   X  ID 
#15919  2 -1.315783 EABE_D5 
#15921  4 -1.304670 EABE_D5 
#15924  2 -1.294728 EABE_D4 
#15926  4 -1.287245 EABE_D4 
0

Это может быть неэффективно. Тем не менее, вы можете сделать это еще один способ использования lapply

do.call(rbind, lapply(split(df, df$ID), function(x) x[seq(2, nrow(x), by=2),])) 


#    Sample X  ID 
#EABE_D4.15924  2 -1.294728 EABE_D4 
#EABE_D4.15926  4 -1.287245 EABE_D4 
#EABE_D5.15919  2 -1.315783 EABE_D5 
#EABE_D5.15921  4 -1.304670 EABE_D5 

split Ting на dataframe, основанный на ID и затем выбирая каждую 2-ю строку в каждой группе и, наконец, rbind ИНГ их с помощью do.call преобразовать список возвращается в качестве dataframe.

Если вы не хотите, имена строк, вы можете взять dataframe одной переменной (скажем), а затем

rownames(a) <- NULL 
Смежные вопросы