【问题标题】:Reshaping data with no time var在没有时间变量的情况下重塑数据
【发布时间】:2017-07-17 16:19:23
【问题描述】:

问题: 如何从现有的数据集生成新的数据集,基本上是从长到宽的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 中应用答案不起作用......

【问题讨论】:

    标签: r reshape


    【解决方案1】:

    我想知道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
    

    【讨论】:

    • 谢谢@gung!这绝对解决了我的问题的一部分。第二部分是:如何将 tab1 从列表转换为数据框,以便将其用作面板数据集并执行分析?简单地用 as.data.frame 强制它是行不通的......
    • @cremorna,我不确定如何轻松做到这一点。问题是你那里有" (100.0)"。我认为有一种方法可以不得到它,但我没有看到它。实现这一点需要一些编码。要为后续处理创建这个,可能有更好的方法。
    • 有效!!非常感谢你!然而,这确实向我证明了我们需要 R 中 Stata 的“collapse”版本,它可以处理因子级别的函数“count”!以防万一有人想将其编程到一个包中:)
    • 不客气,@cremorna。我不认识 Stata,但我怀疑你想要的东西已经存在于某个地方。
    【解决方案2】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      相关资源
      最近更新 更多