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

从频率表中获取“原始”数据

  •  3
  • aL3xa  · 技术社区  · 16 年前

    我一直在四处寻找一些有关美国命名趋势的数据,我设法为2008年出生的婴儿取了1000个名字。数据在此庄园中格式化:

     male.name n.male female.name n.female
     Jacob 22272 Emma 18587
     Michael 20298 Isabella 18377
     Ethan 20004 Emily 17217
     Joshua 18924 Madison 16853
     Daniel 18717 Ava 16850
     Alexander 18423 Olivia 16845
     Anthony 18158 Sophia 15887
     William 18149 Abigail 14901
     Christopher 17783 Elizabeth 11815
     Matthew 17337 Chloe 11699
    

    我想要一个 data.frame 有两个变量: name gender 。 这可以通过循环来完成,但我认为这是解决这个问题的非常低效的方法。我估计有些 reshape 功能将满足我的需要。

    我们假设这个制表符分隔的数据保存到 数据帧 命名 bnames . 循环可以通过以下功能完成:

     tmp <- character()
      for (i in 1:nrow(bnames)) {
      tmp <- c(tmp, rep(bnames[i,1], bnames[i,2]))
     }
    

    但我想用基于向量的方法来实现这一点。有什么建议吗?

    4 回复  |  直到 16 年前
        1
  •  3
  •   Marek    16 年前

    直接基于向量的解决方案(替换循环)将是

    # your data:
    bnames <- read.table(textConnection(
    "male.name n.male female.name n.female
    Jacob 22272 Emma 18587
    Michael 20298 Isabella 18377
    Ethan 20004 Emily 17217
    Joshua 18924 Madison 16853
    Daniel 18717 Ava 16850
    Alexander 18423 Olivia 16845
    Anthony 18158 Sophia 15887
    William 18149 Abigail 14901
    Christopher 17783 Elizabeth 11815
    Matthew 17337 Chloe 11699
    "), sep=" ", header=TRUE, stringsAsFactors=FALSE)
    
    # how to avoid loop
    bnames$male.name[ rep(1:nrow(bnames), times=bnames$n.male) ]
    

    基于这样一个事实 rep 你能在一个循环中立刻做你所做的事情。

    但对于最终结果,您应该结合mropa和gd047答案。

    或者我的解决方案:

    data_final <- data.frame(
      name = c(
        bnames$male.name[ rep(1:nrow(bnames), times=bnames$n.male) ],
        bnames$female.name[ rep(1:nrow(bnames), times=bnames$n.female) ]
      ),
      gender = rep(
        c("m", "f"),
        times = c(sum(bnames$n.male), sum(bnames$n.female))
      ),
      stringsAsFactors = FALSE
    )
    

    [编辑]简化:

    data_final <- data.frame(
      name = rep(
        c(bnames$male.name, bnames$female.name),
        times = c(bnames$n.male, bnames$n.female)
      ),
      gender = rep(
        c("m", "f"),
        times = c(sum(bnames$n.male), sum(bnames$n.female))
      ),
      stringsAsFactors = FALSE
    )
    
        2
  •  5
  •   mropa    16 年前

    所以一个快速的版本是转换data.frame并使用 rbind() 功能 得到你想要的。

    dataNEW <- data.frame(bnames[,1],c("m"), bnames[,c(2,3)], c("f"), bnames[,4])
    colnames(dataNEW) <- c("name", "gender", "value", "name", "gender", "value")
    

    这将给你:

              name gender value      name gender value
    1        Jacob      m 22272      Emma      f 18587
    2      Michael      m 20298  Isabella      f 18377
    3        Ethan      m 20004     Emily      f 17217
    4       Joshua      m 18924   Madison      f 16853
    5       Daniel      m 18717       Ava      f 16850
    6    Alexander      m 18423    Olivia      f 16845
    7      Anthony      m 18158    Sophia      f 15887
    8      William      m 18149   Abigail      f 14901
    9  Christopher      m 17783 Elizabeth      f 11815
    10     Matthew      m 17337     Chloe      f 11699
    

    现在你可以使用 Rbind() :

    dataNGV <- rbind(dataNEW[1:3],dataNEW[4:6])
    

    从而导致:

          name gender value
    1        Jacob      m 22272
    2      Michael      m 20298
    3        Ethan      m 20004
    4       Joshua      m 18924
    5       Daniel      m 18717
    6    Alexander      m 18423
    7      Anthony      m 18158
    8      William      m 18149
    9  Christopher      m 17783
    10     Matthew      m 17337
    11        Emma      f 18587
    12    Isabella      f 18377
    13       Emily      f 17217
    14     Madison      f 16853
    15         Ava      f 16850
    16      Olivia      f 16845
    17      Sophia      f 15887
    18     Abigail      f 14901
    19   Elizabeth      f 11815
    20       Chloe      f 11699
    
        3
  •  3
  •   Yorgos    16 年前

    我认为(如果我理解正确的话)mropa的解决方案还需要一个步骤才能得到你想要的

    library(plyr)
    data <- ddply(dataNGV, .(name,gender), 
          function(x) data.frame(name=rep(x[,1],x[,3]),gender=rep(x[,2],x[,3])))
    
        4
  •  2
  •   Collin    16 年前