【问题标题】:Generating random number by length of blocks of data in R data frame根据R数据帧中数据块的长度生成随机数
【发布时间】:2012-02-04 04:27:22
【问题描述】:

我正在尝试模拟 n 次测量顺序,并查看测量顺序如何影响我的研究对象。为此,我试图为数据框中的新列生成整数随机数。我有一个大数据框,我想根据块中的观察数在数据框中添加一个包含随机数的列。

数据示例(每一行是一个观察):

df <- data.frame(A=c(1,1,1,2,2,3,3,3,3), 
                 B=c("x","b","c","g","h","g","g","u","l"), 
                 C=c(1,2,4,1,5,7,1,2,5))


  A B C
1 1 x 1
2 1 b 2
3 1 c 4
4 2 g 1
5 2 h 5
6 3 g 7
7 3 g 1
8 3 u 2
9 3 l 5

我想做的是添加一个 D 列并根据每个块的长度生成随机整数。块在 A 列中定义。

结果应该是这样的:

df <- data.frame(A=c(1,1,1,2,2,3,3,3,3), 
                 B=c("x","b","c","g","h","g","g","u","l"), 
                 C=c(1,2,4,1,5,7,1,2,5),
                 D=c(2,1,3,2,1,4,3,1,2))

> df
  A B C D
1 1 x 1 2
2 1 b 2 1
3 1 c 4 3
4 2 g 1 2
5 2 h 5 1
6 3 g 7 4
7 3 g 1 3
8 3 u 2 1
9 3 l 5 2

我尝试使用 R:s sample() 函数生成随机数,但我的问题是根据块长度拆分数据并添加新列。非常感谢任何帮助。

【问题讨论】:

  • 欢迎来到 SO,为提供可重现的示例做得很好。

标签: r random split simulation


【解决方案1】:

使用来自plyrddply 真的很容易。

ddply(df, .(A), transform, D = sample(length(A)))

较长的手动版本是:

使用split 按第一列分割数据框。

split_df <- split(df, df$A)

然后对列表中的每个成员调用sample

split_df <- lapply(split_df, function(df) 
{
  df$D <- sample(nrow(df))
  df
})

然后与

重新组合
df <- do.call(rbind, split_df)

【讨论】:

  • @MarkusKorhonen 如果某个答案对您很有效,请单击它旁边的复选标记以“接受”它,并表明您仍然不希望获得更多答案。
  • @shujaa 对不起,我是新来的。谢谢小费。我标记了一个答案。
  • @MarkusKorhonen,不用担心,欢迎来到该网站!而且,正如 Richie 已经评论的那样,提出高质量的第一个问题做得很好。
【解决方案2】:

ave可以轻松搞定

df$D <- ave( df$A, df$A, FUN = function(x) sample(length(x)) )

(你可以用 max() 或其他替换 length(),但即使 A 不是与其块长度匹配的数字,长度也可以工作)

【讨论】:

  • 很好地展示了ave() 的能力。真可惜,像有用的函数有这样一个非常容易误导的名字。即使是?ave 的文档也不能更好地传达它的实际作用。
  • 是的,这有点可惜......我猜他们最初是(平均)愤怒的,当你不指定 FUN 时,它就是这样工作的。
  • 这也是一个很好的解决方案!谢谢帮忙!
【解决方案3】:

一种简单的方法:

df$D = 0

counts = table(df$A)

for (i in 1:length(counts)){
    df$D[df$A == names(counts)[i]] = sample(counts[i])
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-29
    • 2018-11-13
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2011-03-31
    • 2018-03-25
    • 2020-07-30
    相关资源
    最近更新 更多