Search code examples
rloopsrandomshufflesample

randomize values within multiple columns of a data.frame


I'm trying to randomize the values in multiple columns but keep the row and column orders. Also, I only want to randomize values within each column. I basically want to use the function below on multiple columns of a data frame (not just column V1).

sample(myDF$V1)

Edit: here's some sample data with dput:

structure(list(V1 = c(9.883752193648, 15.8168998395206, 20.7796219245553, 
26.8050975188108), V2 = c(11.8173120437042, 14.1136424787568, 
21.4557850824769, 24.5183526363054), V3 = c(10.370627864258, 
14.6684224100574, 19.3556715707687, 25.6203798012984), V4 = c(10.520216457555, 
16.1207126516696, 18.4468625947703, 25.6121234926508), V5 = c(9.24946800549767, 
15.2987236992673, 18.4022904833037, 24.8376890230819)), .Names = c("V1", 
"V2", "V3", "V4", "V5"), class = "data.frame", row.names = c(NA, 
-4L))

Here would be a result for just the V1 column:

>myDF$V1
9.883752193648, 15.8168998395206, 20.7796219245553, 26.8050975188108

>sample(df1$V1)
26.805098  9.883752 15.816900 20.779622

Solution

  • You probably want this. Use lapply which applies sample to each column.

    set.seed(42)  # for sake of reproducibility
    as.data.frame(lapply(myDF, sample))
    #          V1       V2       V3       V4        V5
    # 1 26.805098 21.45579 19.35567 25.61212 24.837689
    # 2 20.779622 14.11364 25.62038 10.52022  9.249468
    # 3  9.883752 24.51835 10.37063 18.44686 18.402290
    # 4 15.816900 11.81731 14.66842 16.12071 15.298724
    

    Edit

    Let's give myDF row names

    rownames(myDF) <- letters[1:4]
    

    we could buffer them

    nm <- rownames(myDF)
    

    and give them back together with the command above.

    set.seed(42)
    myDF <- `rownames<-`(as.data.frame(lapply(myDF, sample)), nm)
    myDF
    #          V1       V2       V3       V4        V5
    # a 26.805098 21.45579 19.35567 25.61212 24.837689
    # b 20.779622 14.11364 25.62038 10.52022  9.249468
    # c  9.883752 24.51835 10.37063 18.44686 18.402290
    # d 15.816900 11.81731 14.66842 16.12071 15.298724
    

    Data

    myDF <- structure(list(V1 = c(9.883752193648, 15.8168998395206, 20.7796219245553, 
    26.8050975188108), V2 = c(11.8173120437042, 14.1136424787568, 
    21.4557850824769, 24.5183526363054), V3 = c(10.370627864258, 
    14.6684224100574, 19.3556715707687, 25.6203798012984), V4 = c(10.520216457555, 
    16.1207126516696, 18.4468625947703, 25.6121234926508), V5 = c(9.24946800549767, 
    15.2987236992673, 18.4022904833037, 24.8376890230819)), class = "data.frame", row.names = c(NA, 
    -4L))