6 votos

Cálculo de proporciones por edad en R

Trabajo en este conjunto de datos con el estado civil y la edad. Quiero trazar el porcentaje de hombres nunca casados frente a cada edad. ¿Podría ayudarme a encontrar la manera de hacerlo en R? Hasta ahora he creado dos matrices separadas con hombres nunca casados y alguna vez casados. Sé cuántos casos de cada uno tengo. Lo que necesito hacer es contar el número de personas que nunca se casaron en cada edad y dividirlo por el número total de personas nunca casadas para obtener un porcentaje. Espero haber sido claro. Gracias

3 votos

¿Podría publicar un fragmento de sus datos, para que tengamos una mejor idea de lo que quiere manipular?

10voto

Brett Veenstra Puntos 10238

Su enfoque me parece demasiado complicado. Empecemos con algunos datos:

## make up some data
status <- factor(rbinom(1000, 1, 0.3), labels = c("single", "married"))
age <- sample(20:50, 1000, replace = TRUE)
df <- data.frame(status, age)
head(df)

Imprime los seis primeros casos:

> head(df)
   status age
1 married  21
2  single  50
3  single  43
4  single  28
5 married  28
6  single  40

A continuación, tenemos que calcular los porcentajes por fila; aunque dudo que esto tenga sentido (se refiere a su declaración: "Lo que tengo que hacer es contar el número de personas que nunca se casaron a cada edad y dividirlo por el número total de personas nunca casadas para obtener un porcentaje").

## calculate row wise percentages (is that what you are looking for?)
(tab <- prop.table(table(df), 1)*100)

La tabla resultante tiene el siguiente aspecto:

> (tab <- prop.table(table(df), 1)*100)
         age
status          20       21       22       23       24       25       26
  single  1.857143 3.142857 3.428571 2.285714 2.142857 2.857143 3.428571
  married 2.333333 2.333333 5.666667 1.333333 3.333333 5.333333 2.000000
         age
status          27       28       29       30       31       32       33
  single  2.857143 3.142857 3.428571 3.285714 2.714286 3.714286 3.571429
  married 5.000000 4.333333 2.666667 4.000000 1.666667 4.666667 3.000000
         age
status          34       35       36       37       38       39       40
  single  3.000000 2.857143 5.000000 3.571429 2.857143 3.571429 3.000000
  married 3.333333 4.000000 4.000000 2.333333 2.000000 2.000000 2.000000
         age
status          41       42       43       44       45       46       47
  single  4.285714 3.000000 3.714286 3.857143 2.857143 3.714286 1.714286
  married 2.333333 3.333333 2.000000 4.333333 3.666667 5.333333 2.666667
         age
status          48       49       50
  single  2.857143 3.428571 4.857143
  married 2.333333 3.000000 3.666667

Es decir, si se suma la fila, da el 100%

> sum(tab[1,])
[1] 100

Por último, trazarlo.

## plot it
plot(as.numeric(dimnames(tab)$age), tab[1,], 
     xlab = "Age", ylab = "Single [%]")

enter image description here

0 votos

Muchas gracias. Eso es exactamente lo que estaba tratando de hacer.

5voto

Dillie-O Puntos 16780

Hace poco hice algo parecido. Hay bastantes maneras de agregar datos como este en R, pero el ddply del paquete plyr es mi manta de seguridad, y recurro a ella para cosas como ésta.

Supongo que tiene registros individuales para cada persona en su conjunto de datos, con edad, sexo y estado civil. No es necesario dividir los datos en varias tablas para este enfoque: si tiene mujeres en la tabla original, déjelas y añada el sexo como variable de agrupación.

require(plyr)
results.by.age <- ddply(.data = yourdata, .var = c("sex", "age"), .fun = function(x) {
    data.frame(n = nrow(x),
               ever.married.n = nrow(subset(x, marital.status %in%
                                            c("Married", "Divorced"))),
               ever.married.prop = nrow(subset(x, marital.status %in%
                                            c("Married", "Divorced"))) / nrow(x)
               )
    }
)

Esto divide el data.frame yourdata por combinaciones únicas de las variables sex y age . A continuación, para cada uno de esos trozos (denominados x ), calcula el número de personas que pertenecen a ese grupo ( n ), cuántos de ellos están casados ( ever.married.n ), y qué proporción de ellos están casados ( ever.married.prop ). Entonces devolverá un data.frame llamado results.by.age con filas como

sex       age    n       ever.married.n     ever.married.prop
"Male"    25     264     167                0.633

Quizá no sea la forma más elegante o eficiente de hacerlo, pero este patrón general me ha resultado muy útil. Una de las ventajas de esto es que puedes recoger fácilmente y de forma transparente cualquier estadística que quieras del subconjunto, lo que puede ser útil si quieres, por ejemplo, añadir una línea de regresión al gráfico (peso por n ) o tener las proporciones masculinas y femeninas en el mismo gráfico y colorear los puntos por sexo.


Aquí hay una versión revisada utilizando el summarise() de plyr - el efecto es el mismo, pero summarise() tiene un par de ventajas clave: - Funciona dentro del entorno del subconjunto actual, por lo que en lugar de escribir x$marital.status Puedo escribir simplemente marital.status . - Me permite referirme a otras variables que ya he creado, lo que facilita mucho los porcentajes, las transformaciones y demás, si ya he hecho num y denom la proporción de num es sólo num / denom .

results.by.age <- ddply(.data = yourdata, .var = c("sex", "age"), .fun = summarise,
    n = length(marital.status),
    ever.married = sum(marital.status %in% c("Married", "Divorced")),
    ever.married.prop = ever.married / n # Referring to vars I just created
)

2voto

Kevin Ballard Puntos 88866

Probablemente lo que necesitas es table o aggregate . Si añades más detalles puedo darte una explicación más profunda.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X