代码之家  ›  专栏  ›  技术社区  ›  cremorna

无时间变量重塑数据

  •  2
  • cremorna  · 技术社区  · 7 年前

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

    我有大量的数据,我提供了以下简化版本:

    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)
    

    所需数据: 我想要一个关于工作及其居住者的数据集,如下所示:

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

      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)
    

    编辑: Transpose / reshape dataframe without "timevar" from long to wide format ,因为我的问题是,我需要用不同的水平数重塑不同的因子变量…应用假设重复Q的答案不起作用。。。

    2 回复  |  直到 7 年前
        1
  •  2
  •   gung - Reinstate Monica    7 年前

    我想知道 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
    
        2
  •  0
  •   cremorna    7 年前

    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