跨多个列的分组功能

时间:2017-05-17 01:25:07

标签: r

我试图通过因子找到多列中的最小值,然后从原始数据帧中减去该最小值。所以说我有这些数据:

testdata <-  data.frame(
  category=factor(rep(c("a","j"),each=6,times=8)), 
  num1=(sample(0:15, 96, replace=TRUE)) + 5, 
  num2=(seq(1:96))
)

我希望通过每个“类别”(a和j)找到列num1和num2的最小值。在现实生活中,我的因子变量更复杂,并且有大量的数值变量。

我能做的最好就是这样:

test2 <- by(testdata, testdata[,"category"], function(x){
  y <- as.data.frame(apply(x[, c(2:3)], 2, min))
})

将它重新组合在一起:

test3 <- do.call(rbind, lapply(test2, data.frame, stringsAsFactors=FALSE))

这似乎有效,但我对如何按组减去最小值感到困惑。想要用sqldf完成我想要的东西:

testdata4 <- sqldf("select a.category, 
                   a.num1-b.num1 as num1, 
                   a.num2-b.num2 as num2 
                   from testdata a left join testdata3 b 
                   on a.category = b.category")

虽然我不想指定每个新变量。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

使用def foo = Action { request => request.session.data.size }

tidyverse

或者,如果您有很多列,并希望自动将其应用于所有列:

library(tidyverse)
# Use set.seed(x) before generating data for future Q's to allow easy checks
#   of the desired output
set.seed(123)

testdata <-  data.frame(
    category=factor(rep(c("a","j"),each=6,times=8)), 
    num1=(sample(0:15, 96, replace=TRUE)) + 5, 
    num2=(seq(1:96))
)

# Generate those same minimums (note that you don't have to do this, just
# showing that you get the same results as your original code)
testdata %>%
    group_by(category) %>%
    summarize(num1 = min(num1), num2 = min(num2))

# Subtract them from the actual data
testdata %>%
    group_by(category) %>%
    mutate(num1_normed = num1 - min(num1),
           num2_normed = num2 - min(num2))

答案 1 :(得分:1)

以下是一些仅使用基数R的方法。ave方法维护行的顺序。

1)使用by作为问题,但使用sweep

Sweep <- function(x) cbind(x[1], sweep(x[-1], 2, apply(x[-1], 2, min), "-"))
do.call("rbind", by(testdata, testdata[[1]], Sweep))

2)ave lapply ave覆盖除第一列之外的列,使用x-min(x)提供列L然后,从{{1}开始1}}维护顺序,在第二行中用原始列替换它们的修改。

ave
相关问题