重塑数据没有时间变化

时间:2017-07-17 16:19:23

标签: r reshape

问题: 如何从现有数据集生成新数据集,基本上它是从长到宽的重塑,但有点复杂。

我有一些非常重要的数据,我在下面提供简化版本:

id      <- c(1,2,3,4,5)
job     <- c(11,12,11,12,13)
sex     <- c(0,1,0,1,0)
country <- c(1,2,3,2,1)
data    <- data.frame(id, job, sex, country)

所需数据: 我想要一份工作及其占用者的数据集,如下所示: 在工作= 11,我有2个性别== 0和1出生在国家== 1和1出生在国家== 3

因此,新数据集将如下所示:

  jobs jobs_sex0 jobs_sex1 jobs_country1 jobs_country2 jobs_country3
1   11         2         0             1             0             0
2   12         0         2             0             2             0
3   13         1         0             0             0             1

我有一种直觉,认为这可以通过tapply实现,但我不确定如何。

我试过这个,但它不起作用:

tapply(occupation[sex==1],sex[sex==1], sum)
aggregate(occupation, list(sex), fun=sum)

编辑: 我认为这个Q不是Transpose / reshape dataframe without "timevar" from long to wide format的重复,因为我遇到的问题是我需要用不同数量的级别重塑不同的因子变量...应用所谓的重复Q的答案不起作用..

2 个答案:

答案 0 :(得分:2)

我想知道tableone package是否可以帮到你。考虑一下:

data$sex     <- factor(data$sex)      # note that you will have to ensure these are factors
data$country <- factor(data$country)

library(tableone)
tab1 <- CreateTableOne(vars=c("sex", "country"), strata="job", data=data)
print(tab1, showAllLevels=TRUE, test=FALSE, explain=FALSE)
#              Stratified by job
#               level 11         12         13        
#   n                 2          2          1         
#   sex         0     2 (100.0)  0 (  0.0)  1 (100.0) 
#               1     0 (  0.0)  2 (100.0)  0 (  0.0) 
#   country     1     1 ( 50.0)  0 (  0.0)  1 (100.0) 
#               2     0 (  0.0)  2 (100.0)  0 (  0.0) 
#               3     1 ( 50.0)  0 (  0.0)  0 (  0.0) 

如果您想进行后续处理,上述解决方案将不太可行。这是一个编码解决方案,但您必须针对每种情况进行调整:

out.data <- t(sapply(split(data, job), function(df){ 
                       with(df, c(table(sex), table(country))) }))
out.data <- data.frame(job=rownames(out.data), out.data)
rownames(out.data)      <- NULL
colnames(out.data)[2:6] <- c(paste("sex",     levels(data$sex),     sep="_"),
                             paste("country", levels(data$country), sep="_") )
out.data
#   job sex_0 sex_1 country_1 country_2 country_3
# 1  11     2     0         1         0         1
# 2  12     0     2         0         2         0
# 3  13     1     0         1         0         0

答案 1 :(得分:0)

我想在一些朋友的帮助下,我找到了另一种非常简单的解决方案:)

data
  id job sex country
1  1  11   2       1
2  2  12   1       2
3  3  11   2       3
4  4  12   1       2
5  5  13   2       1

data$sex <- as.factor(data$sex)
data$country <- as.factor(data$country)

agg_data <- aggregate((model.matrix(~.-1, data[,-(1:2)])), by =         
list(unique.jobs = data$job), FUN=sum)
agg_data

  unique.jobs sex1 sex2 country1 country2 country3
1          11    0    2        1        0        1
2          12    2    0        0        2        0
3          13    0    1        1        0        0