Reputation: 1
I'm new in [r]. And recently i'm stuck in how to perform operation in data.frame. Now I have a data.frame called frame. And I want to transform it to another form.
> 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
the expected form is:
> frame(B=1)
A Freq total
1 0 8 83
2 1 6 27
Can anyone give some suggestions? Thanks
Upvotes: 0
Views: 87
Reputation: 886938
One option would be using dplyr
. We group by 'A', and create a new column 'total' as the sum
of "Freq", filter
the rows where 'B' = 1, and select
all other columns except '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 using data.table
, we convert the data.frame
to data.table
(setDT(frame)
or we can do as.data.table(frame)
), create a new column total
as the sum
of 'Freq', grouped by 'A', subset the rows with B=1, and remove the 'B' column by assigning it to 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
Or using base R
, we create the 'total' using transform/ave
and then subset
the rows that are 1 for '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
Upvotes: 2
Reputation: 1417
Below is an example using functions in the base package - aggregate()
and 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
Upvotes: 0