【问题标题】:dplyr: add jitter to repeated values within a groupdplyr:为组内的重复值添加抖动
【发布时间】:2016-04-26 17:20:00
【问题描述】:

我有一些分组(按Tissue)的数字数据(value)。我想为每个组中多次出现的值添加一个小抖动。

输入:

df <- structure(list(value = c(1.05155243861439, 
1.05155243861439, 1.05155243861439, 11.9769249796958, 1.05155243861439, 
1.05155243861439, 1.05155243861439, 1.05155243861439, 1.05155243861439
), Tissue = structure(c(5L, 5L, 5L, 4L, 5L, 3L, 5L, 1L, 1L
), .Label = c("Brain", "Marrow", "Spleen", "Testes", "Vis"), class = "factor")), .Names = c("value", 
"Tissue"), row.names = c("SM-2", "SM-3", "SM-4", "SM-5", 
"SM-6", "SM-7", "SM-8", "SM-9", "SM-10"), class = "data.frame")

我尝试使用group_bymutate,但这会为每组的每个重复元素添加相同的抖动(有点毫无意义,对吧?)。

df <- df %>%
    group_by(Tissue, value) %>%
    mutate(jitter = ifelse(n()>1, value+runif(1, min=-0.15, max=0.15), value))

输出:

Source: local data frame [9 x 3]
Groups: Tissue, value [4]

      value Tissue     jitter
      (dbl) (fctr)      (dbl)
1  1.051552    Vis  1.1793382
2  1.051552    Vis  1.1793382
3  1.051552    Vis  1.1793382
4 11.976925 Testes 11.9769250
5  1.051552    Vis  1.1793382
6  1.051552 Spleen  1.0515524
7  1.051552    Vis  1.1793382
8  1.051552  Brain  0.9284923
9  1.051552  Brain  0.9284923

第 4 行和第 6 行正确无抖动。但是行[1-3,5,7] 我希望有独特的抖动。来自dplyr 更好的人的任何想法? :(

【问题讨论】:

  • 代替runif(1, ...)添加runif(n(), ...)
  • @Gregor 仍然不应该工作,因为它们出于某种原因同时按 Tissuevalue 分组。尽管仅按 Tissue 分组时它不起作用,因为条件的长度为 1,因此,ifelse 将始终返回长度为 1 的结果。ifelse 通常很烂的众多原因之一。
  • 我会保留最后一句:)
  • 啊,当然。在那种情况下,我会推荐jitter = value + runif(n(), min=-0.15, max=0.15) * (n() &gt; 1)
  • 所以一般的经验法则,最好避免ifelse?像公认答案这样的逻辑向量是更好的方法吗?

标签: r dplyr


【解决方案1】:

正如 cmets 中所指出的,ifelse() 在这种情况下是有问题的,因为它返回的长度必须与测试的长度相同。由于您的测试长度为 1,ifelse 不会返回长度为 n() 的随机数。

我们可以通过将抖动值乘以是否n() &gt; 1 的逻辑来解决这个问题。如果为false,则乘以0;如果为真,则减 1。

df %>%
    group_by(Tissue, value) %>%
    mutate(
        jitter = value + runif(n(), min = -0.15, max = 0.15) * (n() > 1)
    )
#       value Tissue     jitter
#       (dbl) (fctr)      (dbl)
# 1  1.051552    Vis  1.1020925
# 2  1.051552    Vis  1.1398244
# 3  1.051552    Vis  0.9339355
# 4 11.976925 Testes 11.9769250
# 5  1.051552    Vis  1.1186657
# 6  1.051552 Spleen  1.0515524
# 7  1.051552    Vis  1.0249348
# 8  1.051552  Brain  1.0814222
# 9  1.051552  Brain  1.0496148

对于单个条件,您实际上可以使用纯 if(){} else,这也适用于 mutate

jitter = value + if(n() > 1) {runif(n(), -.15, .15)} else 0

你喜欢哪个取决于你。

【讨论】:

  • 我应该注意我是个白痴,并要求抖动错误的列。我实际上是在寻找jitter = as.numeric(Tissue) + runif(n(), min = -0.15, max = 0.15) * (n() &gt; 1)
  • 您可以将位 runif(n(), min = -0.15, max = 0.15) 替换为 jitter(0 * value, amount=0.15)(但可能更难理解发生了什么)
猜你喜欢
  • 2018-10-10
  • 1970-01-01
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 1970-01-01
相关资源
最近更新 更多