Таблицы частот по группам с взвешенными данными в R

#r #group-by #frequency #weighted #frequency-distribution

#r #группировка по #частота #взвешенные #распределение частот

Вопрос:

Я хочу рассчитать два вида таблиц частот по группам с взвешенными данными.

Вы можете генерировать воспроизводимые данные с помощью следующего кода :

 Data <- data.frame(
     country = sample(c("France", "USA", "UK"), 100, replace = TRUE),
     migrant = sample(c("Native", "Foreign-born"), 100, replace = TRUE),
     gender = sample (c("men", "women"), 100, replace = TRUE),
     wgt = sample(100),
     year = sample(2006:2007)
     )
  

Во-первых, я пытаюсь рассчитать таблицу частот статуса мигранта (родной ПРОТИВ иностранного происхождения) по стране и году. Я написал следующий код, используя пакеты questionr и plyr :

 db2006 <- subset (Data, year == 2006)
db2007 <- subset (Data, year == 2007)

result2006 <- as.data.frame(cprop(wtd.table(db2006$migrant, db2006$country, weights=db2006$wgt),total=FALSE))
result2007 <- as.data.frame(cprop(wtd.table(db2007$migrant, db2007$country, weights=db2007$wgt),total=FALSE))

result2006<-rename (result2006, c(Freq = "y2006"))
result2007<-rename (result2007, c(Freq = "y2007"))

result <- merge(result2006, result2007, by = c("Var1","Var2"))
  

В моей реальной базе данных у меня есть 10 лет, поэтому для применения этого кода за все годы требуется время. Кто-нибудь знает более быстрый способ сделать это?

Я также хочу рассчитать долю женщин и мужчин в статусе мигрантов по странам и годам. Я ищу что-то вроде :

 Var1            Var2     Var3     y2006   y2007
Foreign born    France   men        52     55
Foreign born    France   women      48     45
Native          France   men        51     52
Native          France   women      49     48
Foreign born    UK       men        60     65
Foreign born    UK       women      40     35
Native          UK       men        48     50
Native          UK       women      52     50
  

У кого-нибудь есть представление о том, как я могу получить эти результаты?

Ответ №1:

Вы могли бы сделать это, создав функцию с уже написанным вами кодом; используя lapply для повторения этой функции за все годы в ваших данных; затем используя Reduce и merge , чтобы свернуть результирующий список в один фрейм данных. Вот так:

 # let's make your code into a function called 'tallyho'
tallyho <- function(yr, data) {

  require(dplyr)
  require(questionr)

  DF <- filter(data, year == yr)

  result <- with(DF, as.data.frame(cprop(wtd.table(migrant, country, weights = wgt), total = FALSE)))

  # rename the last column by year
  names(result)[length(names(result))] <- sprintf("y%s", year)

  return(result)

}

# now iterate that function over all years in your original data set, then 
# use Reduce and merge to collapse the resulting list into a data frame
NewData <- lapply(unique(Data$year), function(x) tallyho(x, Data)) %>%
  Reduce(function(...) merge(..., all=T), .)
  

Комментарии:

1. ПОКА около Reduce()

2. Большое спасибо @ulfelder за ответ, но у меня возникли некоторые проблемы с этим. Когда я запускаю код, я получаю точно такой же результат для 2006 и 2007 годов, который не correct….Do вы знаете, как я могу это улучшить? Вы знаете, как я могу добавить информацию о поле?

3. Извините, попробуйте отредактированную версию, которую я только что опубликовал. Я думаю, что я запутался dplyr , присвоив функции ввода то же имя, что и столбец. К сожалению, я не думаю, что вы можете добавить пол к этому подходу, поскольку wtd.table , похоже, разрешены только двусторонние перекрестные таблицы. И я недостаточно знаю о том, что делают эти веса, чтобы предложить альтернативное решение.