在R中将行除以它们的总和

时间:2015-07-03 23:30:48

标签: r arithmetic-expressions

我有以下示例数据集:

Example<-data.frame(A=10*1:9,B=10*10:18)

rownames(Example)<-paste("Sample",1:9)
> Example
          A   B
Sample 1 10 100
Sample 2 20 110
Sample 3 30 120
Sample 4 40 130
Sample 5 50 140
Sample 6 60 150
Sample 7 70 160
Sample 8 80 170
Sample 9 90 180

我试图将两列中的每个元素除以其列的总数。我尝试了各种各样的方法,但我觉得我错过了一个基本的代码片段,可以使这更容易。我已经走到了这一步:

ExampleSum1 <- sum(Example[,1])
ExampleSum2 <- sum(Example[,2])

但我不知道如何通过ExampleSum1等划分10,20,30等。

5 个答案:

答案 0 :(得分:4)

您可以使用colSumspaste获取列总和,以便从前一个派生新的列名。 colSums返回列总和的向量,但要进行逐列除法,您需要使用一点技巧。最好的方式是提到@ user20650。

## Make new columns: proportions of column sums
dat[,paste(names(dat),"prop", sep="_")] <- t( t(dat) / colSums(dat) )

dat
#          A   B     A_prop     B_prop
# Sample1 10 100 0.02222222 0.07936508
# Sample2 20 110 0.04444444 0.08730159
# Sample3 30 120 0.06666667 0.09523810
# Sample4 40 130 0.08888889 0.10317460
# Sample5 50 140 0.11111111 0.11111111
# Sample6 60 150 0.13333333 0.11904762
# Sample7 70 160 0.15555556 0.12698413
# Sample8 80 170 0.17777778 0.13492063
# Sample9 90 180 0.20000000 0.14285714

数据

dat <- read.table(text="A      B
Sample1    10     100
Sample2    20     110
Sample3    30     120
Sample4    40     130
Sample5    50     140
Sample6    60     150
Sample7    70     160
Sample8    80     170
Sample9    90     180", header=T)

答案 1 :(得分:4)

data.table解决方案:

sum.cols = c("A", "B")
library(data.table)
setDT(Example, keep.rownames = TRUE)
Example[ , (sum.cols) := lapply(.SD, function(x) x/sum(x)), .SDcols = sum.cols]

或许在你的情况下更直接:

Example[ , c("A", "B") := .(A/sum(A), B/sum(B))]

哪个给:

Example
#          rn          A          B
# 1: Sample 1 0.02222222 0.07936508
# 2: Sample 2 0.04444444 0.08730159
# 3: Sample 3 0.06666667 0.09523810
# 4: Sample 4 0.08888889 0.10317460
# 5: Sample 5 0.11111111 0.11111111
# 6: Sample 6 0.13333333 0.11904762
# 7: Sample 7 0.15555556 0.12698413
# 8: Sample 8 0.17777778 0.13492063
# 9: Sample 9 0.20000000 0.14285714

与使用colSumssweep的方法相比,此方法的主要吸引力在于,这两种方法都需要将您的数据转换为矩阵然后返回,这可能代价高昂。这取决于你的用例;如果你的桌子很小,这些其他方法都很好,这取决于你觉得最可读的东西。

我还注意到没有其他答案提到mapply方法,这种方法几乎适用于任何范例;这是data.table方法:

Example[ , (sum.cols) := mapply(`/`, .SD, lapply(.SD, sum), SIMPLIFY = FALSE), 
        .SDcols = sum.cols]

答案 2 :(得分:2)

这是你之后的事吗?

    id    A   B         A2         B2
 sample 1 10 100 0.02222222 0.07936508
 sample 2 20 110 0.04444444 0.08730159  
 sample 3 30 120 0.06666667 0.09523810
 sample 4 40 130 0.08888889 0.10317460
 sample 5 50 140 0.11111111 0.11111111
 sample 6 60 150 0.13333333 0.11904762
 sample 7 70 160 0.15555556 0.12698413
 sample 8 80 170 0.17777778 0.13492063
 sample 9 90 180 0.20000000 0.14285714

注意:新列A2和B2。

ssh user@host "grep -r -H '<?php \$GLOBALS\[' /var/www/vhosts/"

答案 3 :(得分:2)

仅仅SC.whenStreamingReady

streamingReady();

答案 4 :(得分:1)

你可以这样做:

library(dplyr)
dat %>% mutate_each(funs(. / sum(.)))

给出了:

#           A          B
#1 0.02222222 0.07936508
#2 0.04444444 0.08730159
#3 0.06666667 0.09523810
#4 0.08888889 0.10317460
#5 0.11111111 0.11111111
#6 0.13333333 0.11904762
#7 0.15555556 0.12698413
#8 0.17777778 0.13492063
#9 0.20000000 0.14285714

如果你想保留rownames,请执行:

dat %>% add_rownames("rn") %>% mutate_each(funs(. / sum(.)), -rn)