首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算具有不同分母的不同元素的分列比例。

计算具有不同分母的不同元素的分列比例。
EN

Stack Overflow用户
提问于 2016-02-28 20:55:17
回答 3查看 1.2K关注 0票数 1

我有一个60列表,每列的值如下:是的,不,NA,NP。

代码语言:javascript
复制
    A   B   C
1  YES NO  NO
2  NA  NA  NA
3 YES NO  YES
4  NP  NP  NP

我需要计算多个比例,每个比例都有一个不同的分母:

示例:

“是”和“否”的百分比(YES / (YES + NO))

NP占除NA's以外的所有国家的百分比(NP / (YES + NO + NP))

NA占全部的百分比(NA / rows)

上述数据框架的预期结果:

代码语言:javascript
复制
%YES.A  %NP.A  %NA.A  %YES.B
  100%    33%    25%    0%

到目前为止我尝试过的:

尝试将dplyrmutate结合使用,但需要为60列中的每一列创建7列。每个值四次,每百分比三次。

尝试了revalue,但是太多列的相同问题

代码语言:javascript
复制
mydata$A.NO <- revalue(mydata$A, c("NO" = 1))  
mydata$A.YES <- revalue(mydata$A,c("YES" = 1)) 

希望有人能引导我找到一个更好的解决方案或任何我应该阅读的图书馆。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-28 21:15:04

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

代码语言:javascript
复制
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())

这意味着:

代码语言:javascript
复制
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

通过添加gather(percentage, val, -key)作为最后一步,您可以将此结果重组为与下面相同的格式。

要做到这一点,您可以先总结,然后将其重塑为长格式:

代码语言:javascript
复制
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="_")

这意味着:

代码语言:javascript
复制
  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
票数 2
EN

Stack Overflow用户

发布于 2016-02-28 21:12:20

这是你在基地-R的一个解决方案。由于您只需要摘要度量,所以不需要创建新列。我们只是创建一个新的摘要数据对象。

首先,我们编写一个custum函数来计算一个向量(列)所需的所有内容。我已经做了两个例子,但是您可以很容易地展开:

代码语言:javascript
复制
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
}

然后,我们简单地使用lapply将此函数应用于所有列:

代码语言:javascript
复制
res <- lapply(dat, myfun)

这给出了一个向量列表(您可以很容易地更改函数中的内容;您想要一个列表、向量、数据文件还是data.table?)

我们可以把它们结合起来:

代码语言:javascript
复制
do.call(rbind,res)
  YES        NP
A 1.0 0.3333333
B 0.0 0.3333333
C 0.5 0.3333333
票数 1
EN

Stack Overflow用户

发布于 2016-02-28 22:02:30

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

代码语言:javascript
复制
dt <- data.table(df)
dt[, sapply(.SD, myfun)]

df是原始的数据框架,myfun是Heroka提供的以下功能:

代码语言:javascript
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35688156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档