R 计算具有不同分母的不同元素的按列比例

R 计算具有不同分母的不同元素的按列比例,r,replace,dplyr,R,Replace,Dplyr,我有一个60列的表,每列中都有值,比如:YES,NO,NA,NP A B C 1 YES NO NO 2 NA NA NA 3 YES NO YES 4 NP NP NP 我需要计算多个比例,每个比例都有一个不同的分母: 示例: 是对是和否的百分比(YES/(YES+NO)) NP占除NA以外的所有NP的百分比(NP/(是+否+NP)) NA占所有行的百分比(NA/行) 上述数据框的预期结果: %YES.A %NP.A %NA.A %YES.B 10

我有一个60列的表,每列中都有值,比如:YES,NO,NA,NP

    A   B   C
1  YES NO  NO
2  NA  NA  NA
3 YES NO  YES
4  NP  NP  NP
我需要计算多个比例,每个比例都有一个不同的分母:

示例:
是对是和否的百分比(
YES/(YES+NO)

NP占除NA以外的所有NP的百分比(
NP/(是+否+NP)

NA占所有行的百分比(
NA/行

上述数据框的预期结果:

%YES.A  %NP.A  %NA.A  %YES.B
  100%    33%    25%    0%
到目前为止我所尝试的:
尝试将
dplyr
mutate
一起使用,但需要为60列中的每一列创建7个传统列。每个值四个,每个百分比三个

已尝试重新评估,但列太多的问题相同

mydata$A.NO <- revalue(mydata$A, c("NO" = 1))  
mydata$A.YES <- revalue(mydata$A,c("YES" = 1)) 

mydata$A.NO这里有一个base-R中的解决方案。由于您只需要摘要度量,因此无需创建新列。我们只是创建一个新的摘要数据对象

首先,我们编写一个custum函数来计算一个向量(列)所需的所有内容。我已经完成了您的两个示例,但您可以轻松展开:

myfun <- function(x){
  res <- c(YES=sum(x=="YES",na.rm=T)/sum(x %in% c("YES","NO"),na.rm=T),
                    NP=sum(x=="NP",na.rm=T)/length(na.omit(x)))
  res
}

下面是base-R中的一个解决方案。由于您只需要摘要度量值,因此无需创建新列。我们只是创建一个新的摘要数据对象

首先,我们编写一个custum函数来计算一个向量(列)所需的所有内容。我已经完成了您的两个示例,但您可以轻松展开:

myfun <- function(x){
  res <- c(YES=sum(x=="YES",na.rm=T)/sum(x %in% c("YES","NO"),na.rm=T),
                    NP=sum(x=="NP",na.rm=T)/length(na.omit(x)))
  res
}

我要做的第一步是将数据重塑为长格式,然后按组计算百分比:

library(dplyr)
library(tidyr)

mydf %>% 
  gather(key, val) %>%
  group_by(key) %>% 
  summarise(pYes = 100*sum(val=="YES",na.rm=TRUE)/sum(val %in% c("YES","NO"),na.rm=TRUE),
            pNP = 100*sum(val=="NP",na.rm=TRUE)/sum(val %in% c("YES","NO","NP"),na.rm=TRUE),
            pNA = 100*sum(is.na(val))/n())
其中:

Source: local data frame [3 x 4]

    key  pYes      pNP   pNA
  (chr) (dbl)    (dbl) (dbl)
1     A   100 33.33333    25
2     B     0 33.33333    25
3     C    50 33.33333    25
  column percentage       val
1      A       pYes 100.00000
2      B       pYes   0.00000
3      C       pYes  50.00000
4      A        pNP  33.33333
5      B        pNP  33.33333
6      C        pNP  33.33333
7      A        pNA  25.00000
8      B        pNA  25.00000
9      C        pNA  25.00000
通过添加
gather(percentage,val,-key)
作为最后一步,您可以将此结果重塑为与下面相同的格式


您可以先进行总结,然后将其重塑为长格式:

mydf %>% 
  summarise_each(funs(pYes = sum(.=="YES",na.rm=TRUE)/sum(.%in% c("YES","NO"),na.rm=TRUE),
                      pNP = 100*sum(.=="NP",na.rm=TRUE)/sum(. %in% c("YES","NO","NP"),na.rm=TRUE),
                      pNA = 100*sum(is.na(.))/n())) %>%
  gather(key, val) %>%
  separate(key, c("column","percentage"), sep="_")
其中:

Source: local data frame [3 x 4]

    key  pYes      pNP   pNA
  (chr) (dbl)    (dbl) (dbl)
1     A   100 33.33333    25
2     B     0 33.33333    25
3     C    50 33.33333    25
  column percentage       val
1      A       pYes 100.00000
2      B       pYes   0.00000
3      C       pYes  50.00000
4      A        pNP  33.33333
5      B        pNP  33.33333
6      C        pNP  33.33333
7      A        pNA  25.00000
8      B        pNA  25.00000
9      C        pNA  25.00000

我要做的第一步是将数据重塑为长格式,然后按组计算百分比:

library(dplyr)
library(tidyr)

mydf %>% 
  gather(key, val) %>%
  group_by(key) %>% 
  summarise(pYes = 100*sum(val=="YES",na.rm=TRUE)/sum(val %in% c("YES","NO"),na.rm=TRUE),
            pNP = 100*sum(val=="NP",na.rm=TRUE)/sum(val %in% c("YES","NO","NP"),na.rm=TRUE),
            pNA = 100*sum(is.na(val))/n())
其中:

Source: local data frame [3 x 4]

    key  pYes      pNP   pNA
  (chr) (dbl)    (dbl) (dbl)
1     A   100 33.33333    25
2     B     0 33.33333    25
3     C    50 33.33333    25
  column percentage       val
1      A       pYes 100.00000
2      B       pYes   0.00000
3      C       pYes  50.00000
4      A        pNP  33.33333
5      B        pNP  33.33333
6      C        pNP  33.33333
7      A        pNA  25.00000
8      B        pNA  25.00000
9      C        pNA  25.00000
通过添加
gather(percentage,val,-key)
作为最后一步,您可以将此结果重塑为与下面相同的格式


您可以先进行总结,然后将其重塑为长格式:

mydf %>% 
  summarise_each(funs(pYes = sum(.=="YES",na.rm=TRUE)/sum(.%in% c("YES","NO"),na.rm=TRUE),
                      pNP = 100*sum(.=="NP",na.rm=TRUE)/sum(. %in% c("YES","NO","NP"),na.rm=TRUE),
                      pNA = 100*sum(is.na(.))/n())) %>%
  gather(key, val) %>%
  separate(key, c("column","percentage"), sep="_")
其中:

Source: local data frame [3 x 4]

    key  pYes      pNP   pNA
  (chr) (dbl)    (dbl) (dbl)
1     A   100 33.33333    25
2     B     0 33.33333    25
3     C    50 33.33333    25
  column percentage       val
1      A       pYes 100.00000
2      B       pYes   0.00000
3      C       pYes  50.00000
4      A        pNP  33.33333
5      B        pNP  33.33333
6      C        pNP  33.33333
7      A        pNA  25.00000
8      B        pNA  25.00000
9      C        pNA  25.00000

将数据帧转换为数据表可使其速度提高约50%

dt <- data.table(df)
dt[, sapply(.SD, myfun)]

dt将数据帧转换为数据表可使速度提高约50%

dt <- data.table(df)
dt[, sapply(.SD, myfun)]

dt您的数据有多大?4k行X 144列(4MB)您的数据有多大?4k行X 144列(4MB)数据帧到后面的group by和Summary Geography数据帧到后面的group by和Summary Geography您前面的答案就是我想要的。它可以应用于按数据分组吗?@ErickOGM是的,你可以使用
groupby
进行分组。你之前的答案就是我想要的。它可以应用于按数据分组吗?@ErickOGM是的,您可以使用
groupby
进行分组。