15

いくつかの列の中央値を計算しようとしていますが、私のデータは少し変わっています。次の例のようになります。

library(data.table)

dt <- data.table("ID" = c(1,2,3,4),"none" = c(0,5,5,3), 
                 "ten" = c(3,2,5,4),"twenty" = c(0,2,3,1))


   ID none ten twenty
1:  1    0   3      0
2:  2    5   2      2
3:  3    5   5      3
4:  4    3   4      1

表の列は、その値の出現回数を表します。発生率の中央値を計算したいと思っています。

たとえば、ID = 1 の場合

median(c(10, 10, 10))

作成したい計算です。

ID = 2 の場合

median(c(0, 0, 0, 0, 0, 10, 10, 20, 20))

私は と を使用rep()してみlapply()ましたが、成功は非常に限られており、これを達成する方法について明確なガイダンスを求めています。rep()私は自分の値を繰り返すようにハードコーディングする必要があることを理解しています (例: rep(0,2)or rep(10,2))。これが私が期待することです。各列の繰り返しでリストまたはベクトルを作成するのに苦労しています。

4

4 に答える 4

16

別のdata.table方法は次のとおりです( unique と仮定ID):

dt[, median(rep(c(0, 10, 20), c(none, ten, twenty))), by=ID]
#    ID V1
# 1:  1 10
# 2:  2  0
# 3:  3 10
# 4:  4 10

これは、形を変えずに@eddiの答えを得ようとする試みです(これは最後の手段として使用する傾向があります)。

于 2016-06-01T22:43:35.467 に答える
12

列名を対応する数字に変換するには辞書が必要ですが、それはかなり簡単です。

dict = data.table(name = c('none', 'ten', 'twenty'), number = c(0, 10, 20))

melt(dt, id.var = 'ID')[
  dict, on = c(variable = 'name')][, median(rep(number, value)), by = ID]
#   ID V1
#1:  1 10
#2:  2  0
#3:  3 10
#4:  4 10
于 2016-06-01T21:55:37.950 に答える
6

行ごとの操作と再形成を回避する方法は次のとおりです。

dt[, m := {
    cSD  = Reduce(`+`, .SD, accumulate=TRUE)
    k    = floor(cSD[[length(.SD)]]/2)

    m    = integer(.N)
    for(i in seq_along(cSD)) {
        left = m == 0L
        if(!any(left)) break
        m[left] = i * (cSD[[i]][left] >= k[left])
    }
    names(.SD)[m]
}, .SDcols=none:twenty]

を与える

   ID none ten twenty    m
1:  1    0   3      0  ten
2:  2    5   2      2 none
3:  3    5   5      3  ten
4:  4    3   4      1  ten

ループについては、@alexis_laz のスタイルを借用しています (例: https://stackoverflow.com/a/30513197/ )。

列名の翻訳はスキップしましたが、それは非常に簡単です。c(0,10,20)最後の代わりに使用できますnames(.SD)

于 2016-06-02T00:20:05.487 に答える