2013-02-28 139 views
2

這似乎不應該太困難,但是我對此很難接受。比方說,比如我有以下數據幀:用R中的矢量劃分數據幀或矩陣

set.seed(99) 
data <- data.frame(Names=rep(c('A','B'),5), 
        First = rnorm(10), 
        Second = rnorm(10), 
        Third = rnorm(10)) 

我要的是用平均A的這個我可以通過計算來劃分整個數據幀:

a.mean < - sapply(數據[$名稱==「A」,2:4],平均)

但是當我嘗試通過矢量像這樣把整個數據幀我沒有得到正確的價值觀:

normalized.data <- data[2:4]/a.mean 
normalized.data$Names <- data$Names 
sapply(data[normalized.data$Names == 'A', 2:4], mean) 

First  Second  Third 
0.2578018 -0.5864073 0.1156760 

Wheras我想要的是A的歸一化平均數現在等於1.是否有這樣做的方法?

+0

由於您從未使用過'B'數據,所以讓我們擺脫它 – 2013-02-28 14:15:45

+0

請注意最後一行中的拼寫錯誤。您正在計算原始數據的柱狀圖,而不是標準化數據。 – Roland 2013-02-28 14:21:25

回答

4
set.seed(99) 
data <- data.frame(Names=rep(c('A','B'),5), 
        First = rnorm(10), 
        Second = rnorm(10), 
        Third = rnorm(10)) 

a.mean <- sapply(data[data$Names == 'A', 2:4], mean) 
data[,2:4] <- sweep(data[,2:4],MARGIN=2,a.mean,"/") 

(norm.mean <- sapply(data[data$Names == 'A', 2:4], mean)) 
## First Second Third 
##  1  1  1 

根據您的應用程序,它可能更容易使Names列是該行的名稱改爲:

data <- data.frame(First = rnorm(10), 
        Second = rnorm(10), 
        Third = rnorm(10), 
        row.names=rep(c('A','B'),5)) 

我也喜歡subset(data,Names=='A')的可讀性(雖然不建議用於編程:看https://github.com/hadley/devtools/wiki/Evaluation

+0

與雙轉置除法相比,使用sweep有優勢嗎? – Dave 2013-03-01 01:16:35

+0

我發現它更具可讀性,它同樣適用於行或列操作(通過使用'MARGIN = 1'和'MARGIN = 2',但我不認爲性能差別很大(甚至可能會稍微慢一些)。 – 2013-03-01 02:53:55

2
set.seed(99) 
data <- data.frame(Names=rep(c('A','B'),5), 
        First = rnorm(10), 
        Second = rnorm(10), 
        Third = rnorm(10)) 

a.mean <- colMeans(data[data$Names == 'A', 2:4]) 


normalized.data <- as.data.frame(t(t(data[,2:4])/a.mean)) 


normalized.data$Names <- data$Names 
colMeans(normalized.data[normalized.data$Names == 'A', 1:3]) 

#First Second Third 
#1  1  1 
2

哦,別介意:你沒有按照自己認爲的方式劃分。將矩陣除以值的向量不會將每列除以給定的值。

Rgames> foo 
    [,1] [,2] [,3] 
[1,] 5 3 7 
[2,] 5 3 7 
[3,] 5 3 7 
[4,] 5 3 7 
[5,] 5 3 7 
Rgames> foo/c(1,2,3) 
     [,1] [,2]  [,3] 
[1,] 5.000000 1.0 3.500000 
[2,] 2.500000 3.0 2.333333 
[3,] 1.666667 1.5 7.000000 
[4,] 5.000000 1.0 3.500000 
[5,] 2.500000 3.0 2.333333 
+2

準確地說,除數被回收。這就是爲什麼你可以簡單地轉置foo來獲得想要的結果。 – Roland 2013-02-28 14:30:08