当一些年龄缺失时,R平均超过年龄

时间:2017-06-23 16:24:51

标签: r data.table

我有一个data.table,其中包含Age,食物类别和消耗的kcal列。我试图获得每个类别的平均kcal,但是对于某些类别,该类别中没有消费。所以我不能采用简单的平均值,因为data.table中没有零。

所以对于示例数据:

dtp2 <- data.table(age = c(4,4,4,5,6,18), category = c("chips","vegetables","pizza","chips","pizza","beer"), kcal = c(100,5,100,120,100,150))
只是做dtp2[,mean(kcal),by=category]给出了错误的答案,因为只有18岁的人正在喝啤酒,4-17岁的人不会。

实际数据集是4:18岁,有很多很多类别。我已经尝试使用嵌套的for循环用零填充数据表用于省略的年龄,这非常慢,然后采用上述方法。

是否有一种合理的R方法取平均值kcal,其中假设缺失值为零,而没有嵌套的循环放入零?

2 个答案:

答案 0 :(得分:1)

我认为你想在计算中包含缺失值或0 kcal值。您可以按类别求和,而不是取平均值,除以每个类别的总n。

答案 1 :(得分:0)

Make BufferedReader start from the middle of a .txt file rather than the beginning?相当通用,不会显示任何代码。提到这一点,OP的代码需要修改如下:

library(data.table)
dtp2[, sum(kcal) / uniqueN(dtp2$category), by = category]

返回

     category    V1
1:      chips 55.00
2: vegetables  1.25
3:      pizza 50.00
4:       beer 37.50

请注意uniqueN(dtp2$category)不仅仅使用uniqueN(category),因为按1分组时始终为category

然而,有些情况假设缺失值为零,没有嵌套for循环放入零,就像OP要求的那样。

当数据从长格式转换为宽格式以呈现数据时,可能会出现一种情况:

reshape2::dcast(dtp2, age ~ category, fun = mean, value.var = "kcal", margins = TRUE)
    age beer chips pizza vegetables     (all)
1     4  NaN   100   100          5  68.33333
2     5  NaN   120   NaN        NaN 120.00000
3     6  NaN   NaN   100        NaN 100.00000
4    18  150   NaN   NaN        NaN 150.00000
5 (all)  150   110   100          5  95.83333

这里,保证金平均值仅根据OP要求的可用数据计算。 (请注意,参数fill = 0对边距的计算没有影响。)

因此,在重塑之前,需要填充缺失值。在基数R中,expand.grid()可用于此目的,在data.table它是交叉连接函数CJ()

expanded <- dtp2[CJ(age, category, unique = TRUE), on = .(age = V1, category = V2)
                 ][is.na(kcal), kcal := 0][]
expanded
    age   category kcal
 1:   4       beer    0
 2:   4      chips  100
 3:   4      pizza  100
 4:   4 vegetables    5
 5:   5       beer    0
 6:   5      chips  120
 7:   5      pizza    0
 8:   5 vegetables    0
 9:   6       beer    0
10:   6      chips    0
11:   6      pizza  100
12:   6 vegetables    0
13:  18       beer  150
14:  18      chips    0
15:  18      pizza    0
16:  18 vegetables    0

现在,从长到宽的重塑将返回预期的结果:

reshape2::dcast(expanded, age ~ category, fun = mean, value.var = "kcal", margins = TRUE)
    age  beer chips pizza vegetables   (all)
1     4   0.0   100   100       5.00 51.2500
2     5   0.0   120     0       0.00 30.0000
3     6   0.0     0   100       0.00 25.0000
4    18 150.0     0     0       0.00 37.5000
5 (all)  37.5    55    50       1.25 35.9375