calculer la médiane à partir de données.colonnes du tableau en R
j'essaie de calculer une valeur médiane à travers un certain nombre de colonnes, cependant mes données sont un peu funky. Il ressemble à l'exemple suivant.
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
Dans le tableau de la colonne représente le nombre d'occurrences de cette valeur. Je veux calculer l'occurrence médiane.
par exemple pour ID = 1
median(c(10, 10, 10))
est le calcul que je veux faire.
ID = 2
median(c(0, 0, 0, 0, 0, 10, 10, 20, 20))
j'ai essayé d'utiliser rep()
et lapply()
avec un succès très limité et je suis après quelques directives claires sur la façon dont cela pourrait être réalisé. Je comprends pour les goûts de rep()
je serais d'avoir à coder en dur ma valeur à être répétée (par exemple,rep(0,2)
ou rep(10,2)
) et c'est ce que j'attends. Je suis juste mal pour créer une liste ou un vecteur avec les répétitions de chaque colonne.
4 réponses
en voici un autre data.table
chemin (en supposant 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
c'est juste une tentative pour obtenir la réponse de @eddi sans remodeler (que j'ai tendance à utiliser en dernier recours).
Vous avez besoin d'un dictionnaire pour traduire les noms de colonnes en nombres correspondants, et puis c'est assez simple:
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
voici un moyen d'éviter les opérations de contournement et le remodelage:
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]
ce qui donne
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
Pour la boucle, je suis d'emprunt @alexis_laz style, par exemple,https://stackoverflow.com/a/30513197/
j'ai sauté la traduction des noms de colonne, mais c'est assez simple. Vous pouvez utiliser c(0,10,20)
au lieu de names(.SD)
à la fin.
Voici un rowwise
dplyr
:
dt %>% rowwise %>%
do(med = median(c(rep(0, .$none), rep(10, .$ten), rep(20, .$twenty)))) %>%
as.data.frame
med
1 10
2 0
3 10
4 10
inspiré par la réponse de @Arun, cela fonctionne aussi:
dt %>% group_by(ID) %>%
summarise(med = median(rep(c(0, 10, 20), c(none, ten, twenty))))
Source: local data table [4 x 2]
ID med
(dbl) (dbl)
1 1 10
2 2 0
3 3 10
4 4 10