2017-02-08 2 views
2

у меня есть огромный кадр данных (A) в R, который выглядит следующим образом:С R, перебрать кадры данных, выполнять математические операции на каждых из них, добавить результаты в новом кадре данных

Letters Frequency Numbers 
a   0.15  1 
b   0.67  2 
c   0.85  7 
d   0.4   3 

Я хотел бы к первому разделить на 4 кадров данных в соответствии с диапазоном значений в столбце «Частота» (4 частотных бинов размером 0,25), которые идут от 0 до 1, так что я получаю:

A1 [0, 0.25] 

Letters Frequency Numbers 
a   0.15  1 

A2 [0.25, 0.5] 

Letters Frequency Numbers 
d   0.4   3 

A3 [0.5, 0.75] 

Letters Frequency Numbers 
b   0.67  2 

A4 [0.75, 1] 

Letters Frequency Numbers 
c   0.85  7 

в одном итерационным способом и следуя порядку частотных бункеров, я хотел бы выполнять математические операции в A1, A2, A3 и A4 (например, op1 = Numbers - 2; OP2 = Числа * 10) и создать фрейм данных B с прилагаемыми результатами:

B 

bin   op1 op2 
[0, 0.25]  -1  10 
[0.25, 0.5]  1  30 
[0.5, 0.75]  0  20 
[0.75, 1]  5  70 

Я думаю, мне не нужно создавать А1, А2, А3 и А4 (в идеале я хотел бы работать только с) и что есть более элегантный способ получить B путем итерации через ящики частот напрямую, но я создал их в этом примере, чтобы четко объяснить принцип. Я думаю, что это можно сделать с лапкой, но я не уверен, как это сделать. Заранее большое спасибо.

ответ

2

Метод базового R с методикой разделенного применения-Комбайн

do.call(rbind, lapply(split(dd, findInterval(dd$Frequency, c(0, .25, .5, .75, 1))), 
         function(i) within(i, { # create variables, remove Numbers 
             op1 <- Numbers - 2 
             op2 <- Numbers * 10 
             Numbers <- NULL}))) 

Это возвращает

Letters Frequency op2 op1 
1  a  0.15 10 -1 
2  d  0.40 30 1 
3  b  0.67 20 0 
4  c  0.85 70 5 

Здесь findInterval бункеров наблюдения проводились на основе частоты, split разделяет data.frame на основе на этих ячейках и заказах соответствующие данные, lapply и within используются для построения новых переменных для каждой группы.

+0

Большое спасибо @ Имо. Было бы здорово получить ваши отзывы о последнем комментарии, который я опубликовал. – Lucas

+0

Если вы ссылаетесь на свой комментарий в ответе mr-flick, у меня возникают проблемы с его визуализацией. Из моего второго чтения кажется, что он достаточно разный, чтобы опубликовать новый вопрос с хорошим примером, иллюстрирующим эту проблему. – lmo

2

Вы можете сделать это с помощью простого group_by в dplyr. Например, с вашими данными.

dd<-read.table(text="Letters Frequency Numbers 
a   0.15  1 
b   0.67  2 
c   0.85  7 
d   0.4   3", header=T) 

Вы можете запустить

library(dplyr) 

dd %>% 
    group_by(bin=cut(Frequency, breaks=seq(0,1,by=.25))) %>% 
    transmute(op1=Numbers-2, op2=Numbers*10) %>% 
    arrange(bin) 

Мы используем cut() создать биннинговые группы, а затем использовать transmute(), чтобы создать новые столбцы (при удалении старого).

+0

Спасибо @MrFlick, это также сработало. Могу ли я спросить вас, как вы будете делать это итеративно (или с dplyr), если я захочу выполнить эти математические операции на вспомогательных фреймах данных, которые содержат все строки, которые в определенном столбце (например, «Письма») имеют определенные слова, такие как «genic», , Проблема в том, что эти слова входят в контекст, например, «genic/intronic/missense», и поэтому я не могу группировать их только «гениальным». Я знаю, как извлечь эти вспомогательные фреймы с помощью grepl и делать это вручную, но я не могу сделать это элегантным способом. Огромное спасибо. – Lucas

+0

Непонятно, что вы имеете в виду. Вы должны создать новое сообщение с воспроизводимым примером с образцом ввода и желаемым выходом, как в этом вопросе. – MrFlick