簡體   English   中英

R-從數據框中該組的每個元素中減去該組的平均值

[英]R- Subtracting the mean of a group from each element of that group in a dataframe

我正在嘗試將向量“均值”合並到數據幀。 我的數據框看起來像這樣數據=增長

我首先使用以下命令計算了不同組(1組=人口+溫度+大小+復制數)的所有均值:

means<-aggregate(TL ~ Population + Temperature + Replicat + Size + Measurement, data=growth, list=growth$Name, mean)        

然后,我選擇測量1的方法如下,因為我只對這些方法感興趣。

meansT0<-means[which(means$Measurement=="1"),]    

現在,我想將此均值向量合並到我的數據框(=增長)中,以便每個組的正確均值對應於數據框的正確部分。

然后,目標是將每個組的平均值(在度量1中)基於其所屬組(以及對於除度量1之外的所有其他度量)而言的數據框的每個元素。 也許不需要在數據框中添加均值列? 您知道執行此操作的命令嗎?

[27.06.18]我組成了這個簡化的數據框,希望對我有所幫助。 因此,我要對數據框中的每個個體和每個度量(這里只有度量1和度量2,通常我有更多)進行求和,以其度量1的所屬組的平均值為基礎。

因此,如果我按組得到平均值( 1組 =人口+溫度+測量值):

means<-aggregate(TL ~ Population + Temperature + Measurement, data=growth, list=growth$Name, mean)
means               

我得到了均值的這些值(在此示例中):

Population Temperature Measurement       TL
JUB          15           **1**           **12.00000**
JUB          20           **1**           **15.66667**
JUB          15           2           17.66667
JUB          20           2           18.66667
JUB          15           3           23.66667
JUB          20           3           24.33333

我們只對測量1中的方法感興趣。對於數據框中的每個人,我想在測量1中將其所屬組的平均值相乘(在此示例中,請參見帶有R命令的數據框):- 對於JUB + 15組+測量1的平均值= 12- 對於JUB + 20組+測量1的平均值= 15.66

growth<-data.frame(Population=c("JUB", "JUB", "JUB","JUB", "JUB", "JUB","JUB", "JUB", "JUB","JUB", "JUB", "JUB","JUB", "JUB", "JUB","JUB", "JUB", "JUB"), Measurement=c("1","1","1","1","1","1","2","2","2","2","2","2", "3", "3", "3", "3", "3", "3"),Temperature=c("15","15","15","20", "20", "20","15","15","15","20", "20", "20","15","15","15","20", "20", "20"),TL=c(11,12,13,15,18,14, 16,17,20,21,19,16, 25,22,24,26,24,23), New_TL=c("11-12", "12-12", "13-12", "15-15.66", "18-15.66", "14-15.66", "16-12", "17-12", "20-12", "21-15.66", "19-15.66", "16-15.66", "25-12", "22-12", "24-12", "26-15.66", "24-15.66", "23-15.66"))    
print(growth)

我希望借此,您可以更好地了解我要做什么。 我有很多數據,如果必須手動執行此操作,這將花費我很多時間,並增加了我犯錯誤的風險。

這是tidyverse一個選項。 在按組列分組后,使用mutate_at指定感興趣的列,並獲得該列( . )與其mean的差。

library(tidyverse)
growth %>% 
       group_by(Population, Temperature, Replicat, Size, Measurement) %>% 
       mutate_at(vars(HL, TL), funs(MeanGroupDiff = . 
                  - mean(.[Measurement == 1])))

mtcars數據集中使用可重現的示例

data(mtcars)
mtcars %>%
   group_by(cyl, vs) %>% 
   mutate_at(vars(mpg, disp), funs(MeanGroupDiff = .- mean(.[am==1])))

您是否考慮過使用data.table包? 它非常適合執行您描述的此類分組,過濾,聯接和聚合操作,從長遠來看可能會節省大量時間。

下面的代碼顯示了與您描述的工作流程類似但基於內置mtcars數據集的工作流程如何使用data.table看起來。

需要明確的是,還有一些方法可以使用base R以及其他軟件包(如dplyr來完成您描述的dplyr ,只是根據我發現對個人工作最有用的建議提出建議。

library(data.table)

## Convert mtcars to a data.table
## only include columns `mpg`, `cyl`, `am` and `gear` for brevity
DT <- as.data.table(mtcars)[, .(mpg, cyl,am, gear)]

## Take a subset where `cyl` is equal to 6
DT <- DT[cyl == 6]

## Calculate grouped mean based on `gear` and `am` as grouping variables
DT[,group_mpg_avg := mean(mpg), keyby = .(gear, am)]

## Calculate each row's difference from the group mean
DT[,mpg_diff_from_group := mpg - group_mpg_avg]

print(DT)

#     mpg cyl am gear group_mpg_avg mpg_diff_from_group
# 1: 21.4   6  0    3         19.75                1.65
# 2: 18.1   6  0    3         19.75               -1.65
# 3: 19.2   6  0    4         18.50                0.70
# 4: 17.8   6  0    4         18.50               -0.70
# 5: 21.0   6  1    4         21.00                0.00
# 6: 21.0   6  1    4         21.00                0.00
# 7: 19.7   6  1    5         19.70                0.00

考慮by因素對數據框架進行子集化(但為了比較第1組和所有其他組而省略了Measurement )。 然后,對所需的列運行ifelse條件邏輯計算。 由於by將返回數據幀列表,因此請使用do.call()將所有外部綁定:

df_list <- by(growth, growth[,c("Population", "Temperature")], function(sub) {
  # TL CORRECTION      
  sub$Correct_TL <- ifelse(sub$Measurement != 1, 
                           sub$TL - mean(subset(sub, Measurement == 1)$TL),
                           sub$TL)
  # ADD OTHER CORRECTIONS

  return(sub)  
})

final_df <- do.call(rbind, df_list)

輸出 (使用發布的數據)

final_df

#    Population Measurement Temperature TL   New_TL Correct_TL
# 1         JUB           1          15 11    11-12 11.0000000
# 2         JUB           1          15 12    12-12 12.0000000
# 3         JUB           1          15 13    13-12 13.0000000
# 7         JUB           2          15 16    16-12  4.0000000
# 8         JUB           2          15 17    17-12  5.0000000
# 9         JUB           2          15 20    20-12  8.0000000
# 13        JUB           3          15 25    25-12 13.0000000
# 14        JUB           3          15 22    22-12 10.0000000
# 15        JUB           3          15 24    24-12 12.0000000
# 4         JUB           1          20 15 15-15.66 15.0000000
# 5         JUB           1          20 18 18-15.66 18.0000000
# 6         JUB           1          20 14 14-15.66 14.0000000
# 10        JUB           2          20 21 21-15.66  5.3333333
# 11        JUB           2          20 19 19-15.66  3.3333333
# 12        JUB           2          20 16 16-15.66  0.3333333
# 16        JUB           3          20 26 26-15.66 10.3333333
# 17        JUB           3          20 24 24-15.66  8.3333333
# 18        JUB           3          20 23 23-15.66  7.3333333

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM