#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
, похоже, разрешены только двусторонние перекрестные таблицы. И я недостаточно знаю о том, что делают эти веса, чтобы предложить альтернативное решение.