2016-10-19 89 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) 
    ) 

首先,我试图计算的移民身份的频率表(本机VS外国出生)的国家和年份。我写了使用包questionrplyr下面的代码:

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在数据中遍历所有年份的函数;然后使用Reducemerge将结果列表折叠为一个数据帧。像这样:

# 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