按数据框中的组划分不同组的中位数

Sco*_*hal 2 r

我有一个包含列group_ID和class多个数字特征的数据框,以及一些字符元数据,即:

group_ID  class  var1  var2  var3  metadata
a         foo    1     324   3     cat
a         bar    1.3   34    53    dog
a         baz    31    34    5     elephant
b         foo    34    34    943   dolphin
b         bar    94    51    23    chipmunk
b         baz    985   595   43    badger
c         foo    43    93    23    tapir
c         bar    43    23    23    monkey
c         baz    40    53    512   duck
Run Code Online (Sandbox Code Playgroud)

我想计算foo每个类的中位数group_ID,然后将每一行除以匹配的中位数group_ID.

在这个例子中我只有1行每个foo,所以中间将是相同的初始值,但在现实中,我为每个许多行class和group_ID.


有一个简单的方法吗?我对far的最佳尝试包括为中值创建一个单独的数据帧foo,然后在一个可怕的循环中按group_ID和扫描进行拆分,但最终我失去了元数据列.这样做似乎很常见,我确信我错过了一些东西.

任何帮助,将不胜感激.

Pie*_*une 7

我们可以使用mutate_eachfrom dplyr除以条件.

library(dplyr)
df %>% group_by(group_ID) %>%
  mutate_each(funs(./median(.[class == "foo"])), var1:var3)
# Source: local data frame [9 x 6]
# Groups: group_ID
# 
#   group_ID class       var1       var2        var3 metadata
# 1        a   foo  1.0000000  1.0000000  1.00000000      cat
# 2        a   bar  1.3000000  0.1049383 17.66666667      dog
# 3        a   baz 31.0000000  0.1049383  1.66666667 elephant
# 4        b   foo  1.0000000  1.0000000  1.00000000  dolphin
# 5        b   bar  2.7647059  1.5000000  0.02439024 chipmunk
# 6        b   baz 28.9705882 17.5000000  0.04559915   badger
# 7        c   foo  1.0000000  1.0000000  1.00000000    tapir
# 8        c   bar  1.0000000  0.2473118  1.00000000   monkey
# 9        c   baz  0.9302326  0.5698925 22.26086957     duck
Run Code Online (Sandbox Code Playgroud)

如果OP想要将这些列添加为新的/附加列并保持以前的数据不变,您可以将上述方法修改为:

df %>% 
  group_by(group_ID) %>%
  mutate_each(funs(./median(.[class == "foo"])), setNames(var1:var3, paste0("varN", 1:3)))
Run Code Online (Sandbox Code Playgroud)


akr*_*run 5

这是一个data.table解决方案.我们将'data.frame'转换为'data.table'(setDT(df)),按'group_ID'分组,我们循环(with lapply)通过以列名'var'开头的列子grep集(使用我们是子集),除每列由该列median的子集对应于'class'中的'foo'值.这可以:=作为新列分配(),或者我们可以将其分配回同一列以替换原始列.替换原始列的一个问题是我们应该将原始列与替换的列匹配class.如果'var'列的原始类是numeric,那么它将作为median计算和除法将新列转换为numeric.如果原始列是integer类,则可能的选项是将类更改为numeric然后分配.

library(data.table)
setDT(df)[, paste0("varN", 1:3) := lapply(.SD[, 
     grep("^var", names(.SD)), with=FALSE], 
         function(x) x/median(x[class=="foo"])), group_ID]
df
# group_ID class  var1 var2 var3 metadata      varN1      varN2       varN3
#1:        a   foo   1.0  324    3      cat  1.0000000  1.0000000  1.00000000
#2:        a   bar   1.3   34   53      dog  1.3000000  0.1049383 17.66666667
#3:        a   baz  31.0   34    5 elephant 31.0000000  0.1049383  1.66666667
#4:        b   foo  34.0   34  943  dolphin  1.0000000  1.0000000  1.00000000
#5:        b   bar  94.0   51   23 chipmunk  2.7647059  1.5000000  0.02439024
#6:        b   baz 985.0  595   43   badger 28.9705882 17.5000000  0.04559915
#7:        c   foo  43.0   93   23    tapir  1.0000000  1.0000000  1.00000000
#8:        c   bar  43.0   23   23   monkey  1.0000000  0.2473118  1.00000000
#9:        c   baz  40.0   53  512     duck  0.9302326  0.5698925 22.26086957
Run Code Online (Sandbox Code Playgroud)

  • 从统计上考虑它.对于你收到的100个upvotes你得到一个downvote.统计上无关紧要.:) (2认同)