2016-10-19 21 views
1

Я хочу рассчитать два типа частотных таблиц по группам с взвешенными данными.Таблицы частот по группам с взвешенными данными в 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) 
    ) 

Во-первых, я пытаюсь вычислить таблицу частот статуса мигранта (Native VS иностранных рождения) по стране и году. Я написал следующий код, используя пакеты 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 

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

ответ

0

Вы можете сделать это, выполнив функцию с кодом, который вы уже написали; используя 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), .) 
+0

TIL о 'Reduce()' – roman

+0

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

+0

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