2015-05-16 2 views
0

Я новичок в [r]. И недавно я застрял в том, как выполнять операцию в data.frame. Теперь у меня есть data.frame, называемый frame. И я хочу преобразовать его в другую форму.преобразовать фрейм данных в другую форму

> frame 
     A  B Freq total 
1  0  0 75 110 
2  1  0 21 110 
3  0  1 8 110 
4  1  1 6 110 

ожидаемая форма:

> frame(B=1) 
     A Freq total 
1  0  8 83 
2  1  6 27 

Может кто-нибудь дать некоторые предложения? Спасибо

+0

Лучше всего объяснить словами, что вы хотите, а не просто показать вход и выход. – Frank

+0

Вы хотите получить полные значения A, равные 0, общие значения B, равные 0, и то же самое для A и B, но с 1? Кажется, что есть несогласованность в трансформации, которую вы имеете в ожидаемой форме. –

+0

извините. Я забыл сказать, что B = 1 – Program

ответ

2

Один вариант использовал бы dplyr. Мы группа по «А», а также создать новый столбец «всего» в качестве sum из «Freq», filter рядам, где «B» = 1, и select все остальные столбцы, кроме «B»

library(dplyr) 
frame %>% 
    group_by(A) %>% 
    mutate(total= sum(Freq)) %>% 
    filter(B==1)%>% 
    select(-B) 
# A Freq total 
#1 0 8 83 
#2 1 6 27 

Or используя data.table, мы преобразовать data.frame к data.table (setDT(frame) или мы можем сделать as.data.table(frame)), создать новый столбец total как sum из «Freq», сгруппированных по «A», подмножество строк с в = 1, и удалите «B ', присвоив его NULL.

library(data.table) 
setDT(frame)[, total:= sum(Freq), A][B==1][,B:=NULL] 
# A Freq total 
#1: 0 8 83 
#2: 1 6 27 

Или с помощью base R, мы создаем «общее» с помощью transform/ave, а затем subset строки, которые являются 1 для «B».

subset(transform(frame, total=ave(Freq, A, FUN=sum)), B==1, select=-B) 
# A Freq total 
#3 0 8 83 
#4 1 6 27 
+0

Что такое setDT? – Program

+0

@Program добавлено некоторое объяснение – akrun

0

Ниже приведен пример использования функции в базовом пакете - aggregate() и merge().

frame <- read.table(header = T, text = " 
A  B Freq total 
1  0  0 75 110 
2  1  0 21 110 
3  0  1 8 110 
4  1  1 6 110") 

# obtain sum by column A 
frame1 <- aggregate(frame$Freq, by = list(frame$A), sum) 
names(frame1) <- c("A", "total") 

# merge Freq 
frame2 <- merge(frame1, frame[frame$B == 1, c(1,3)], by="A") 
# A total Freq 
#1 0 83 8 
#2 1 27 6 
Смежные вопросы