Обмен значениями фрейма данных случайным образом между различными децилями фрейма данных - PullRequest
0 голосов
/ 05 ноября 2019

Это немного сложно объяснить, поэтому я надеюсь, что это достаточно ясно, но если нет, я попытаюсь расширить его.

Итак, у меня есть такой фрейм данных:

df <- data.frame(index=sort(runif(300, -10,10)), v1=runif(300, -2,-1), v2=runif(300, 1,2))

Это дает нам 3-колоночный 300-рядный df. Первый столбец («index») содержит отсортированные значения от -10 до 10, а следующие два столбца («v1» / «v2») содержат случайные числовые значения, которые не важны для этой проблемы.

СейчасЯ классифицирую свои строки df в децилях в соответствии со столбцом индекса (например, дециль 1: места 1-30, дециль 2: места 31-60), и я хочу произвольно менять местами строки так, чтобы все значения 1-го дециля менялись случайным образомс 6-м децилем все значения 2-го дециля меняются случайным образом с 7-м децилем и так далее. Когда я говорю swapped, я имею в виду, что значение индекса остается на своем месте, но значения v1 и v2 меняются местами (все еще связаны) с v1 и v2 случайной строки в соответствующем дециле.

Например,v1 и v2 первого ряда в df (и, следовательно, из 1-го дециля) будут заменены v1 и v2 160-го ряда в df (6-м дециле), v1 и v2 второго ряда в df(1-й дециль) поменяется местами v1 и v2 175-й строки в df (также 6-й децил), v1 и v2 31-й строки в df (2-й децил) поменяется местами v1 и v2186-я строка в df (7-й дециль) и т. Д., Поэтому все значения v1 + v2 случайным образом меняются местами в соответствии с их соответствующим новым децилем.

Надеюсь, все ясно. Я пытался решить это часами и не мог понять.

Спасибо

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

Использование order() для сортировки по двум индексам, один из которых - переставленные децили, другой - случайный.

set.seed(123)
dtf <- data.frame(round(cbind(index=sort(runif(20, -10, 10)), 
                                 v1=runif(20, 0, 5), 
                                 v2=runif(20, 5, 10)), 2))
ea <- nrow(dtf)/10

# Deciles shifted by 5
d <- rep(((1:10 + 4) %% 10) + 1, each=ea)

# Random index within decile
r <- c(replicate(10, sample(ea)))

cbind(dtf, z=dtf[order(d, r), -1])
#    index   v1   v2 z.v1 z.v2
# 12 -9.16 4.45 5.71 4.51 7.21
# 11 -9.09 3.46 7.07 4.82 5.23
# 14 -7.94 3.20 7.07 3.98 5.61
# 13 -5.08 4.97 6.84 3.45 8.99
# 15 -4.25 3.28 5.76 0.12 7.80
# 16 -3.44 3.54 5.69 2.39 6.03
# 17 -1.82 2.72 6.17 3.79 5.64
# 18 -0.93 2.97 7.33 1.08 8.77
# 19 -0.87 1.45 6.33 1.59 9.48
# 20  0.56 0.74 9.29 1.16 6.87
# 2   1.03 4.82 5.23 3.46 7.07
# 1   1.45 4.51 7.21 4.45 5.71
# 3   3.55 3.45 8.99 3.20 7.07
# 4   5.77 3.98 5.61 4.97 6.84
# 6   7.66 0.12 7.80 3.54 5.69
# 5   7.85 2.39 6.03 3.28 5.76
# 8   8.00 3.79 5.64 2.97 7.33
# 7   8.81 1.08 8.77 2.72 6.17
# 10  9.09 1.59 9.48 0.74 9.29
# 9   9.14 1.16 6.87 1.45 6.33
0 голосов
/ 05 ноября 2019

Я думаю, что это то, что вам нужно.

swapByBlocks <- function(df, blockSize = 30, nblocks = 10){
    if((nrow(df) != blockSize*nblocks) || nblocks %%2) stop("Undefined behaviour")
    swappedDF <- df[c((nrow(df)/2 +1):nrow(df), 1:(nrow(df)/2)),]
    ndxMat <- sapply(1:(nblocks/2),function(dummy) sample(1:blockSize))
    for(i in 1:ncol(ndxMat)) {
        swappedDF[(i-1)*blockSize + 1:blockSize, ] <- swappedDF[((i-1)*blockSize + 1:blockSize)[ndxMat[,i]], ]
        swappedDF[(i+nblocks/2-1)*blockSize + 1:blockSize, ] <- swappedDF[((i+nblocks/2-1)*blockSize + 1:blockSize)[order(ndxMat[,i])], ]
    }   
    return(swappedDF)                
}

Небольшой случай, когда вы можете проверить, как это работает:

res <- swapByBlocks(df[1:18,], blockSize = 3, nblocks = 6)
> df[1:18,]
       index        v1       v2
1  -9.859624 -1.657779 1.954094
2  -9.774898 -1.015825 1.006341
3  -9.624402 -1.713754 1.527065
4  -9.441129 -1.891834 1.803793
5  -9.424195 -1.125674 1.581199
6  -8.890537 -1.142044 1.219111
7  -8.838012 -1.173445 1.013408
8  -8.296938 -1.780396 1.570550
9  -8.172076 -1.789056 1.178596
10 -7.671897 -1.988539 1.690468
11 -7.655868 -1.095662 1.876414
12 -7.450011 -1.337443 1.632104
13 -7.204528 -1.880350 1.408944
14 -7.085862 -1.232293 1.593247
15 -7.030691 -1.087031 1.924306
16 -6.989892 -1.639967 1.495058
17 -6.978945 -1.395340 1.872944
18 -6.930379 -1.841031 1.061046
> res
       index        v1       v2
10 -7.450011 -1.337443 1.632104
11 -7.655868 -1.095662 1.876414
12 -7.671897 -1.988539 1.690468
13 -7.030691 -1.087031 1.924306
14 -7.085862 -1.232293 1.593247
15 -7.204528 -1.880350 1.408944
16 -6.989892 -1.639967 1.495058
17 -6.930379 -1.841031 1.061046
18 -6.978945 -1.395340 1.872944
1  -9.624402 -1.713754 1.527065
2  -9.774898 -1.015825 1.006341
3  -9.859624 -1.657779 1.954094
4  -8.890537 -1.142044 1.219111
5  -9.424195 -1.125674 1.581199
6  -9.441129 -1.891834 1.803793
7  -8.838012 -1.173445 1.013408
8  -8.172076 -1.789056 1.178596
9  -8.296938 -1.780396 1.570550
> 

Здесь 18 строк с шестью блоками по три числа в каждом. Ряды с 1 по 3 меняются местами с рядами с 10 по 12, рядами с 4 по 6 с рядами с 13 по 15 и рядами с 4 по 7 с рядами с 16 по 17.

...