2017-06-13 178 views
2

我想将聚合函数和百分比函数应用于列。我发现讨论聚合的线程(Calculating multiple aggregations with lapply(.SD, ...) in data.table R package)和讨论百分比的线程(How to obtain percentages per value for the keys in R using data.table?Use data.table to calculate the percentage of occurrence depending on the category in another column),但不是两者。使用data.table计算百分比和其他函数

请注意,我正在寻找基于data.table的方法。 dplyr不适用于实际数据集。

下面的代码来生成的示例数据:

set.seed(10) 
    IData <- data.frame(let = sample(x = LETTERS, size = 10000, replace=TRUE), numbers1 = sample(x = c(1:20000),size = 10000), numbers2 = sample(x = c(1:20000),size = 10000)) 
    IData$let<-as.character(IData$let) 

    data.table::setDT(IData) 

这里的代码使用dplyr

Output <- IData %>% 
    dplyr::group_by(let) %>% 
    dplyr::summarise(numbers1.mean = as.double(mean(numbers1)),numbers1.median = as.double(median(numbers1)),numbers2.mean=as.double(mean(numbers2)),sum.numbers1.n = sum(numbers1)) %>% 
    dplyr::ungroup() %>% 
    dplyr::mutate(perc.numbers1 = sum.numbers1.n/sum(sum.numbers1.n)) %>% 
    dplyr::select(numbers1.mean,numbers1.median,numbers2.mean,perc.numbers1) 

样本输出(标题) 如果我运行head(output)生成输出,我将得到:

let numbers1.mean numbers1.median numbers2.mean perc.numbers1 
    <chr>   <dbl>   <dbl>   <dbl>   <dbl> 
    N  10320.951   10473.0  9374.435 0.03567927 
    H  9683.590   9256.5  9328.035 0.03648391 
    L  10223.322   10226.0  9806.210 0.04005400 
    S  9922.486   9618.0  10233.849 0.03678742 
    C  9592.620   9226.0  9791.221 0.03517997 
    F  10323.867   10382.0  10036.561 0.03962035 

这里就是我试图用data.table(失败)

IData[, as.list(unlist(lapply(.SD, function(x) list(mean=mean(x),median=median(x),sum=sum(x))))), by=let, .SDcols=c("numbers1","numbers2")] [,.(Perc = numbers1.sum/sum(numbers1.sum)),by=let] 

我有2个问题:

a)本使用data.table我怎样才能解决?

b)我已经看到上面的线程已经使用prop.table。有人可以指导我如何使用这个功能?

我会真诚地感谢任何指导。

回答

1

我们可以用类似的方法与data.table

res <- IData[, .(numbers1.mean = mean(numbers1), 
      numbers1.median = median(numbers1), 
      numbers2.mean=mean(numbers2), 
      sum.numbers1.n = sum(numbers1)), let 
      ][, perc.numbers1 := sum.numbers1.n/sum(sum.numbers1.n) 
      ][, c("let", "numbers1.mean", "numbers1.median", 
         "numbers2.mean", "perc.numbers1"), with = FALSE] 

head(res) 
# let numbers1.mean numbers1.median numbers2.mean perc.numbers1 
#1: N  10320.951   10473.0  9374.435 0.03567927 
#2: H  9683.590   9256.5  9328.035 0.03648391 
#3: L  10223.322   10226.0  9806.210 0.04005400 
#4: S  9922.486   9618.0  10233.849 0.03678742 
#5: C  9592.620   9226.0  9791.221 0.03517997 
#6: F  10323.867   10382.0  10036.561 0.03962035 
+0

抱歉愚蠢的问题:如果我不上面的代码分配给'res'什么也没有发生。这与'dplyr'不同,如果我不指定任何东西,'dplyr'会在屏幕上输出结果,但在上面的情况下用'data.table',这不会发生。为什么这样?我会很感激你的想法。 – watchtower

+1

@watchtwoer如果您检查第一个'[]',我们正在进行汇总,而不是在原始数据集中创建一列。通过分配':='只有我们创建一个新的列。但是,在这段代码中,发生在第一个'[]'之后,所以它不会更新原始数据。 – akrun

+0

感谢您的回复,并对我的不清楚表示歉意。我认为我已经得到了':='部分,以及第一个'[]'和第二个'[]'之间的区别。如果我把'res <-'部分(分配给res),我不确定为什么上面的代码不能在屏幕上打印任何东西。看到结果的唯一方法是执行'res'。相反,如果没有分配,'dplyr'总是打印结果。我希望这个时候我的问题很清楚。我会很感激你的帮助。 – watchtower