【问题标题】:Stuck with a 2 data frames row copy卡住了 2 个数据框行副本
【发布时间】:2014-11-13 01:53:34
【问题描述】:

我决定学习 R 并且正在阅读 R 书中的科学编程简介 (http://www.ms.unimelb.edu.au/spuRs/)

我目前卡在这本书的第 7 章问题 3 上,问题是:

考虑以下非常简单的遗传模型。一个人口包括 两种性别的数量相等:男性和女性。在每一代男人和 女性是随机配对的,每对正好产生两个后代, 一男一女。我们对高度分布感兴趣 从一代到下一代。假设两个孩子的身高 只是父母身高的平均值,怎么分布 几代人的身高变化?

将当前一代的高度表示为具有两个的数据框 两个性别的变量 m 和 f。命令 rnorm(100, 160, 20) 将根据正态分布生成一个长度为 100 的向量 平均值为 160,标准差为 20(参见第 16.5.1 节)。我们用它来 在第 1 代随机生成种群:

pop <- data.frame(m = rnorm(100, 160, 20), f = rnorm(100, 160, 20))

命令 sample(x, size = length(x)) 将返回一个随机样本 大小取自向量 x 的大小(无需替换)。 (也会 如果可选参数 replace 设置为 TRUE,则带有替换的示例。) 以下函数采用数据框弹出并随机排列 男人的命令。然后男女按排配对, 和下一代的高度是通过取平均值来计算的 每一行。该函数返回一个具有相同结构的数据帧,给出 下一代的高度。

next.gen <- function(pop) {
pop$m <- sample(pop$m)
pop$m <- apply(pop, 1, mean)
pop$f <- pop$m
return(pop)
}

使用函数next.gen生成九代,然后使用格子 函数直方图绘制每个男性身高的分布 生成,如图 7.7 所示。你看到的现象叫做回归 到平均数。

提示:构造一个带有变量 height 和 generation 的数据框,其中 每行代表一个人。

我已经构建了一个空白数据框:

generations <- data.frame(gen="", height="")

现在我正试图将第一代高度信息放入其中,所以我运行:

next.gen(pop)

generations$height <- pop$m

我收到以下错误:

Error in `$<-.data.frame`(`*tmp*`, "height", value = c(165.208323681597,  : 
replacement has 100 rows, data has 1

我知道我正在尝试将 pop$m 数据帧中的信息压缩到 generation$height 的单行中,这导致了问题,我不知道如何解决这个问题?我认为空白数据框足够灵活,可以在从弹出数据框复制行时添加行?

然后我尝试运行此代码:

generations <- pop$m

我得到了 100 个值,但这只是将我的世代数据框变成了我认为并运行的向量

generations

仅列出向量中复制的值。

我认为我的第一步是错误的,我的数据框定义是否正确?为什么我不能将行信息从 1 个数据帧复制到一个空数据帧中,然后根据需要调整空数据帧的大小?

谢谢

【问题讨论】:

    标签: r


    【解决方案1】:

    不确定您要查找的确切输出。这是一种应该足够简单的方法。 ** 注意:有很多可行的方法。

    pop <- data.frame(m = rnorm(100, 160, 20), f = rnorm(100, 160, 20))
    
    next.gen <- function(pop) {
      pop$m <- sample(pop$m)
      pop$m <- apply(pop, 1, mean)
      pop$f <- pop$m
      return(pop)
    }
    
    # the code
    test <- list()
    for (i in 1:9) {
      test[[i]] <- next.gen(pop)["m"]
      test[[i]]$generation <- paste0("g", i)
    }
    library(data.table)
    test2 <- rbindlist(test)
    
    
    # result
                m generation
      1: 174.6558         g1
      2: 143.2617         g1
      3: 185.2829         g1
      4: 168.9719         g1
      5: 151.6948         g1
     ---                    
    896: 159.6091         g9
    897: 161.4546         g9
    898: 171.8679         g9
    899: 138.4982         g9
    900: 152.7390         g9
    

    【讨论】:

    • 非常感谢帮忙,没想到用list()填充数据
    • 欢迎。就速度和紧凑性而言,这肯定不是最好的方法。但相信这有助于人们了解和理解他是否需要进一步前进。
    【解决方案2】:

    试试:

    > generations <- data.frame(gen="", height="", stringsAsFactors=F)
    > for(i in 1:length(pop$m)) generations[i,] = c("",pop$m[i])
    > generations
        gen           height
    1        136.70042632318
    2       153.985392293761
    3       122.077485676327
    4       166.582538529591
    5       170.751368839498
    6         190.8894492681
    ...
    

    【讨论】:

    • 感谢您的帮助,我将查看此版本和以下版本。
    猜你喜欢
    • 2018-08-30
    • 2015-01-28
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 2022-01-22
    • 2019-02-06
    • 1970-01-01
    相关资源
    最近更新 更多