【问题标题】:Creating a new data.frame variable using sample(), with maximum sample() value differing by row使用 sample() 创建一个新的 data.frame 变量,最大 sample() 值因行而异
【发布时间】:2018-09-20 18:23:00
【问题描述】:

我有一个 12071 行的数据框 foo。我正在尝试,对于foo 的每一行,基于 1:K 生成一个随机值,并将其插入新列 L。例如,第一行应给出介于 1 和 5 之间的 L 值,第二个应该给出 1 到 9 之间的值,第三个应该给出 1 到 3 之间的值,依此类推。这些值必须是整数,因此我尝试使用sample()。在每一行内,范围内的任何整数都有相同的选择概率。

我已经减少了代码中的列数,因为它们无关紧要,而且我在示例中遇到了数据包装问题。 A 列和 K 列是链接的,因此 A 列中的字符串在 K 列中始终具有相同的值。由于 A 列值不唯一,因此存在重复的 A/K 组合。

数据(列减少):

A           B     C     D               E     F             G       ... K    
A011100     F     7     Partnered       4     40-49 Hrs     0.04075     5
A011200     M     7     Partnered       4     40-49 Hrs     0.13334     9
A011400     F     8     Non-partnered   2     30-39 Hrs     0.02310     3
A011500     F     4     Non-partnered   4     1-9 Hrs       0.94519     4
A012100     M     8     Partnered       4     40-49 Hrs     0.78114     4

我的代码无法正常工作。对于 data.frame 中的每一行,我无法计算出将新的最大值传递给 sample() 的逻辑,并在每一行中正确构造它。

我尝试了以下方法:

foo$L <- lapply(foo, sample(1:foo$K,1))

这给了:

match.fun(FUN) 中的错误: 'sample(1:foo$K, 1)' 不是函数、字符或符号 另外:警告信息: 在 1:foo$K 中: 数值表达式有 12071 个元素:只使用第一个

然后

foo$L <- lapply(foo, function(x) sample(1:foo$K,1))

由此产生的错误是:

$&lt;-.data.frame(*tmp*, L, value = list(A = 1L, : 替换有12行,数据有12071 另外:有12条警告(使用warnings()查看)

然后

foo$L <- replicate(nrow(foo), sample(foo, 1:foo$K,1))

这给了

有 50 个或更多警告(使用 warnings() 查看前 50 个)

【问题讨论】:

    标签: r dataframe random iteration conditional-operator


    【解决方案1】:

    我们可以使用sapply 来做sample

    df$L <- sapply(df$K, function(x) sample(x, 1))
    
    #        A B C K L
    #1 A011100 F 7 5 1
    #2 A011200 M 7 9 7
    #3 A011400 F 8 3 2
    #4 A011500 F 4 4 2
    #5 A012100 M 8 4 1
    

    取自?sample

    如果 x 的长度为 1,是数字(在 is.numeric 的意义上)并且 x >= 1,则通过 sample 进行采样从 1:x 开始。

    因此,对于df$K 的每个值,我们从sapply 中的1:x 对其进行采样,然后随机选择其中一个值。

    PS - 为了简单和更好的可见性,我进一步减少了列。

    【讨论】:

      【解决方案2】:

      我认为 Ronak Shah 的回答比我的要好,但对于 dplyr 解决方案,请尝试:

      library(dplyr)
      
      desired_df <- mutate(rowwise(foo), L = sample(K,1))
      

      输出:

      A           B     C     D               E     F             G           K     L 
      A011100     F     7     Partnered       4     40-49 Hrs     0.04075     5     4
      A011200     M     7     Partnered       4     40-49 Hrs     0.13334     9     7
      A011400     F     8     Non-partnered   2     30-39 Hrs     0.02310     3     1
      A011500     F     4     Non-partnered   4     1-9 Hrs       0.94519     4     3
      A012100     M     8     Partnered       4     40-49 Hrs     0.78114     4     1
      

      【讨论】:

      • 感谢您提供的 dplyr 示例,它非常简单。我试图避免添加额外的包(我有这么多!),我相信你的例子会对使用 dplyr 的人有所帮助。 R 的乐趣,有很多不同的方式来做同样的事情!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 2020-09-14
      • 1970-01-01
      • 2020-05-02
      • 2015-08-22
      • 2019-05-13
      • 2021-01-02
      相关资源
      最近更新 更多