【问题标题】:apply() and calculating proportion of first row for all dataframe rowsapply() 并计算所有数据帧行的第一行的比例
【发布时间】:2011-04-06 02:18:42
【问题描述】:

我有一个如下所示的数据框,列出了按车辆类型划分的受伤人数:

trqldnum <- data.frame(motorveh=c(796,912,908,880,941,966,989,984),
                       motorcyc=c(257,295,326,313,403,389,474,496),
                       bicyc=c(109,127,125,137,172,146,173,178))
trqldnum

#  motorveh motorcyc bicyc
#1      796      257   109
#2      912      295   127
#3      908      326   125
#4      880      313   137
#5      941      403   172
#6      966      389   146
#7      989      474   173
#8      984      496   178

目前我正在计算每种车辆类型的第一行的比例:

trqldprop <- t(apply(trqldnum,1,function(x) {
                 x/c(trqldnum[1,1],trqldnum[1,2],trqldnum[1,3])
              }))
trqldprop

#  motorveh motorcyc    bicyc
#1 1.000000 1.000000 1.000000
#2 1.145729 1.147860 1.165138
#3 1.140704 1.268482 1.146789
#4 1.105528 1.217899 1.256881
#5 1.182161 1.568093 1.577982
#6 1.213568 1.513619 1.339450
#7 1.242462 1.844358 1.587156
#8 1.236181 1.929961 1.633028

这看起来有点难看,如果数据改变了形状,我需要手动更改函数的分母。如果我尝试在 apply() 语句中使用以下内容,我最终会在列表列表中得到输出。

function(x) x/c(trqldnum[1,])

我宁愿以上述数据框结果结束,但我只是在试图弄清楚这一点时陷入困境。

【问题讨论】:

    标签: r rows apply divide


    【解决方案1】:

    将数据框转换为矩阵并使用矩阵运算:

    m <- as.matrix(trqldnum)
    
    trqldprop <- as.data.frame( t(t(m)/m[1,]) )
    
    > trqldprop
      motorveh motorcyc    bicyc
    1 1.000000 1.000000 1.000000
    2 1.145729 1.147860 1.165138
    3 1.140704 1.268482 1.146789
    4 1.105528 1.217899 1.256881
    5 1.182161 1.568093 1.577982
    6 1.213568 1.513619 1.339450
    7 1.242462 1.844358 1.587156
    8 1.236181 1.929961 1.633028
    

    请注意,我们需要转置矩阵(请参阅t(m)),因为当您将矩阵除以向量时,操作是按列进行的。

    【讨论】:

    • 不错的答案,如果我有足够的声誉,我会 +1 你。我承认我对矩阵运算不是很精通,所以我今天有一个主题要阅读。
    【解决方案2】:

    我喜欢这些任务的plyr,因为它们允许您指定输出格式。您可以将其转换为一个函数,该函数可以轻松扩展到更多列和不同的基本级别以进行划分。

    FUN <- function(dat, baseRow = 1){
        require(plyr)   
        divisors <- dat[baseRow ,]
        adply(dat, 1, function(x) x / divisors)
    }
    
    FUN(trqldnum, 1)
    
      motorveh motorcyc    bicyc
    1 1.000000 1.000000 1.000000
    2 1.145729 1.147860 1.165138
    3 1.140704 1.268482 1.146789
    4 1.105528 1.217899 1.256881
    5 1.182161 1.568093 1.577982
    6 1.213568 1.513619 1.339450
    7 1.242462 1.844358 1.587156
    8 1.236181 1.929961 1.633028
    

    【讨论】:

      【解决方案3】:

      怎么样

      sweep(trqldnum,2,unlist(trqldnum[1,]),"/")
      

      ?

      需要unlist将数据框的第一行转换成可以扫的向量...

      【讨论】:

        【解决方案4】:

        某些版本的 Prasad 解决方案没有转换为矩阵。

        trqldnum/trqldnum[1,][rep(1,nrow(trqldnum)),]
        

        【讨论】:

        • 今天重复了类似的分析后,我意识到这可以通过使用... trqldnum/trqldnum[rep(1,nrow(trqldnum)),] 进一步简化
        猜你喜欢
        • 1970-01-01
        • 2015-01-15
        • 2020-05-30
        • 2014-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-08
        • 2020-06-11
        相关资源
        最近更新 更多