在R中的两列之间随机化数据

时间:2016-10-03 02:25:11

标签: r permutation

我已经搜索了这项任务的答案或解决方案但尚未成功,所以如果这是多余的话我会道歉。

我想在两列之间随机化数据。这是为了模拟植被野外数据中的物种错误识别,所以我想在两列之间分配某种错误识别概率。我想有一些方法可以使用sample或" permute"封装

我将为一个例子选择一些现成的数据。

library (vegan)
data (dune)

如果您键入head (dune),则可以看到这是一个数据框,其中网站为行和种类为列。为方便起见,我们可以假设一些现场技术有可能错误识别 Poa pratensis Poa trivialis

poa = data.frame(Poaprat=dune$Poaprat,Poatriv=dune$Poatriv)
head(poa)
           Poaprat      Poatriv
1             4            2
2             4            7
3             5            6
4             4            5
5             2            6
6             3            4

将这两列之间的值随机化的最佳方法是什么(彼此之间进行转换和/或当两者都存在时添加到一列)。结果数据可能如下所示:

           Poaprat      Poatriv
1             6            0
2             4            7
3             5            6
4             5            4
5             0            7
6             4            3

P.S。

对于那里的生态学家:请注意,我已经为了时间而制作了这个例子,并且我知道相对封面值不是附加的。我为需要这样做而道歉。

***编辑:为了更加清晰,随机化的数据类型将是覆盖率估计值(因此值介于0%和100%之间)。此快速示例中的数据是相对覆盖估计值,而不是计数值。

3 个答案:

答案 0 :(得分:1)

您仍然需要用新的列替换实际的列,并且可能有一种更优雅的方式来执行此操作(它在EDT的最后阶段)你& #39;我们必须决定除了你想要使用的正常发行版之外的其他内容(即你将如何替换sample()你得到你的掉期和加法用:

library(vegan)
library(purrr)

data(dune)

poa <- data.frame(
  Poaprat=dune$Poaprat,
  Poatriv=dune$Poatriv
)

map2_df(poa$Poaprat, poa$Poatriv, function(x, y) {
  for (i in 1:length(x)) {
    what <- sample(c("left", "right", "swap"), 1)
    switch(
      what,
      left={ 
        x[i] <- x[i] + y[i]
        y[i] <- 0
      },
      right={ 
        y[i] <- x[i] + y[i]
        x[i] <- 0
      },
      swap={
        tmp <- y[i]
        y[i] <- x[i]
        x[i] <- tmp
      }
    )
  }
  data.frame(Poaprat=x, Poatriv=y)
})

答案 1 :(得分:0)

这是我的方法:

让我们定义一个函数,该函数将采用多个标本(n)和一个概率(p)来标记错误。此函数将对概率为p的1和带有1-p的0进行采样。这种随机抽样的总和将给出n个样本中有多少是不正确的。

mislabel = function(x, p){
    N_mis = sample(c(1,0), x, replace = T, prob = c(p, 1-p))
    sum(N_mis)
}

定义函数后,将其应用于每个列并将其存储到两个新列中

p_miss = 0.3

poa$Poaprat_mislabeled = sapply(poa$Poaprat, mislabel, p_miss)
poa$Poatriv_mislabeled = sapply(poa$Poatriv, mislabel, p_miss)

每个物种标记的最终标本数量可以通过从同一物种中减去错误并从另一个物种中添加不正确的数据来计算。

poa$Poaprat_final = poa$Poaprat - poa$Poaprat_mislabeled + poa$Poatriv_mislabeled
poa$Poatriv_final = poa$Poatriv - poa$Poatriv_mislabeled + poa$Poaprat_mislabeled

<强>结果:

> head(poa)
  Poaprat Poatriv Poaprat_mislabeled Poatriv_mislabeled Poaprat_final Poatriv_final
1       4       2                  0                  0             4             2
2       4       7                  1                  2             5             6
3       5       6                  0                  3             8             3
4       4       5                  1                  2             5             4
5       2       6                  0                  3             5             3
6       3       4                  1                  2             4             3

完成程序:

mislabel = function(x, p){
    N_mis = sample(c(1,0), x, replace = T, prob = c(p, 1-p))
    sum(N_mis)
}


p_miss = 0.3

poa$Poaprat_mislabeled = sapply(poa$Poaprat, mislabel, p_miss)
poa$Poatriv_mislabeled = sapply(poa$Poatriv, mislabel, p_miss)

poa$Poaprat_final = poa$Poaprat - poa$Poaprat_mislabeled + poa$Poatriv_mislabeled
poa$Poatriv_final = poa$Poatriv - poa$Poatriv_mislabeled + poa$Poaprat_mislabeled

p_miss变量是两个物种不正确标记的概率。你也可以使用不同的值来模拟一个非对称的机会,与另一个相比,它可能更容易错误标记其中一个。

答案 2 :(得分:0)

我只想在接受hrbrmstr的回答后办理登机手续。考虑到今天的一点时间,我继续做了一个功能,以一定程度的灵活性完成这项任务。它允许包含多个物种对,不同物种对之间的不同概率(不同方向的不对称性),并明确包括值保持不变的概率。

misID = function(X, species,probs = c(0.1,0.1,0,0.8)){
library(purrr)

X2 = X

if (!is.matrix(species) == T){
as.matrix(species)
}


if (!is.matrix(probs) == T){
probs=matrix(probs,ncol=4,byrow=T)
}

if (nrow(probs) == 1){
probs = matrix(rep(probs[1,],nrow(species)),ncol=4,byrow=T)
}

for (i in 1:nrow(species)){

Spp = data.frame(X[species[i,1]],X[species[i,2]])


mis = map2_df(Spp[1],Spp[2],function(x,y) {
  for(n in 1:length(x)) {
    what = sample(c('left', 'right', 'swap','same'), size=1,prob=probs[i,])
    switch(
      what,
      left = {
        x[n] = x[n] + y[n]
        y[n] = 0
      },
      right = {
        y[n] = x[n] + y[n]
        x[n] = 0
      },
      swap = {
        tmp = y[n]
        y[n] = x[n]
        x[n] = tmp
      },
      same = {
      x[n] = x[n]
      y[n] = y[n]
      }
    )
}
misSpp = data.frame(x,y)
colnames(misSpp) =c(names(Spp[1]),names(Spp[2]))
return(misSpp)

})
X2[names(mis[1])] = mis[1]
X2[names(mis[2])] = mis[2]
}
return(X2)
}

这里可能存在一些轻微的低效率,但总的来说它完成了我需要它做的事情。对不起,没有评论,但我确实弄清楚如何处理将混洗数据轻松地放入数据框。

感谢您指出&#34; purrr&#34;包给我以及switch函数。

示例:

library(vegan)
library(labdsv)
data(dune)

#First convert relative abundances to my best guess at the % values in Van der Maarel (1979)
code = c(1,2,3,4,5,6,7,8,9)
value = c(0.1,1,2.5,4.25,5.5,20,40,60.5,90)
veg = vegtrans(dune,code,value)

specpairs = matrix(c("Poaprat","Poatriv","Trifprat","Trifrepe"),ncol=2,byrow=T) #create matrix of species pairs
probmat = matrix(c(0.3,0,0,0.7,0,0.5,0,0.5),ncol=4,byrow=T)                     #create matrix of misclassification probabilities

veg2 = misID(veg,specpairs,probs = probmat) 

print(veg2)