简体   繁体   中英

How can I sort a data.frame (table) based on another object's row.names

I have to write a report where the cross table is ordered based on the frequency of another table. I'm building the first table using the following code:

library(descr)

X <- c(rep('Anthony', 6), rep('Marcelo', 4), rep('Luiz', 3), rep('Lind', 2), rep('Cesar', 1), rep('Outros', 6), rep('Ninguém', 6), rep('NS/NR', 6)) 
PESO <- rep(1, length(X))
REG <- sample(c('R1','R2','R3','R4'), length(X), replace=T)
bd <- data.frame(X, PESO, REG)

perc <- (round(freq(bd$X, w=bd$PESO, plot=F), digits=0))
perc <- perc[rownames(perc)!="NA's" & rownames(perc)!='NR' & rownames(perc)!='Total',]
perc <- perc[,-1]
ns <- perc[names(perc)=='NS/NR']
ni <- perc[names(perc)=="Ninguém"]
ou <- perc[names(perc)=="Outros"]
perc <- data.frame('%'=sort(perc[names(perc)!='NS/NR' & names(perc)!="Ninguém" & names(perc)!="Outros"], decreasing=T))
perc <- rbind(perc,ou,ni,ns)
rownames(perc)[rownames(perc)==6 | rownames(perc)==7 | rownames(perc)==8] <- c('Outros', 'Ninguém', 'NS/NR')
perc <- rbind(perc, Total=100, Base=dim(bd)[1])

The outcome is

         X.
Anthony  18
Marcelo  12
Luiz      9
Lind      6
Cesar     3
Outros   18
Ninguém  18
NS/NR    18
Total   100
Base     34

Now, when I run the code to cross this variable with another one, I get

tab <- round(rbind(prop.table(xtabs(PESO~X+REG, bd),margin=2)*100))
ns <- tab[rownames(tab)=='NS/NR',]
ni <- tab[rownames(tab)=="Ninguém",]
ou <- tab[rownames(tab)=="Outros",]
tab <- tab[rownames(tab)!='NS/NR' & rownames(tab)!="Ninguém" & rownames(tab)!="Outros",]
tab <- tab[order(tab[,1], decreasing=T),]
perc <- rbind(tab,ou,ni,ns,Total=100,Base=apply(xtabs(PESO~X+REG, bd), 2, sum))
rownames(perc)[rownames(perc)=='ou' | rownames(perc)=='ni' | rownames(perc)=='ns'] <- c('Outros', 'Ninguém', 'NS/NR')
perc <- perc[,colnames(perc)!='Total']

The outcome is

         R1  R2  R3  R4
Anthony  17  14  25  11
Luiz     17  14   0  11
Marcelo  17   0  17  11
Cesar     0   0   0  11
Lind      0   0  17   0
Outros    0  43  17  11
Ninguém  33  14  17  11
NS/NR    17  14   8  33
Total   100 100 100 100
Base      6   7  12   9

I would like to make this table to have the same order as the first one. Something like:

         R1  R2  R3  R4
Anthony  17  14  25  11
Marcelo  17   0  17  11
Luiz     17  14   0  11
Lind      0   0  17   0
Cesar     0   0   0  11 
Outros    0  43  17  11
Ninguém  33  14  17  11
NS/NR    17  14   8  33
Total   100 100 100 100
Base      6   7  12   9

How can I adapt my code to solve this?

Thanks

After your first block capture the row order

perc <- rbind(perc, Total=100, Base=dim(bd)[1])
#add
perc.order <- rownames(perc)

Then you can use those row names to sort your final data. So after

perc <- perc[,colnames(perc)!='Total']
#add
perc[perc.order, ]

You can index an element that has row names using those names as long as they are passed as a character vector. This will only return values that were in the first table. If new values were added, they will not be included in the output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM