데이터 프레임을 행 및 열 방향으로 무작위 화 (또는 영구화)하는 방법은 무엇입니까?


96

이와 같은 데이터 프레임 (df1)이 있습니다.

     f1   f2   f3   f4   f5
d1   1    0    1    1    1  
d2   1    0    0    1    0
d3   0    0    0    1    1
d4   0    1    0    0    1

d1 ... d4 열은 행 이름이고 f1 ... f5 행은 열 이름입니다.

sample (df1)을 수행하기 위해 df1과 동일한 개수가 1 인 새 데이터 프레임을 얻습니다. 따라서 1의 개수는 전체 데이터 프레임에 대해 보존되지만 각 행이나 각 열에 대해서는 보존되지 않습니다.

무작위 화를 행 단위 또는 열 단위로 수행 할 수 있습니까?

각 열에 대해 df1을 열 단위로 무작위 화하고 싶습니다. 즉, 각 열의 1 개 수가 동일하게 유지됩니다. 각 열은 한 번 이상 변경해야합니다. 예를 들어, 다음과 같은 무작위 df2를 가질 수 있습니다. (각 열의 1 개수는 동일하게 유지되지만 각 행의 1 개수는 다릅니다.

     f1   f2   f3   f4   f5
d1   1    0    0    0    1  
d2   0    1    0    1    1
d3   1    0    0    1    1
d4   0    0    1    1    0

마찬가지로 각 행에 대해 df1을 행 단위로 무작위 화하고 싶습니다. 각 행의 1 중 1은 동일하게 유지되며 각 행을 변경해야합니다 (그러나 변경된 항목의 수는 다를 수 있음). 예를 들어, 무작위 df3은 다음과 같을 수 있습니다.

     f1   f2   f3   f4   f5
d1   0    1    1    1    1  <- two entries are different
d2   0    0    1    0    1  <- four entries are different
d3   1    0    0    0    1  <- two entries are different
d4   0    0    1    0    1  <- two entries are different

추신. 두 개의 열을 무작위로 지정하는 것에 대한 이전 질문에 대한 이전 답변에 대해 Gavin Simpson, Joris Meys 및 Chase의 도움에 감사드립니다.


열을 동시에 변경 하시겠습니까 ? 이것을 다시 읽으면 열 제약 조건 (각 열에서 동일한 수의 1)이 두 번째 행 순열 예에서 유지되지 않은 것처럼 보입니다.
Gavin Simpson

1
여러 계정에 가입하지 마십시오. 나는 이전 Q.에 사용되는 여기에 사용되는 계정 병합 중재자를 요청했습니다
개빈 심슨

답변:


233

R data.frame이 주어지면 :

> df1
  a b c
1 1 1 0
2 1 0 0
3 0 1 0
4 0 0 0

행 방향 셔플 :

> df2 <- df1[sample(nrow(df1)),]
> df2
  a b c
3 0 1 0
4 0 0 0
2 1 0 0
1 1 1 0

기본적으로 sample()첫 번째 인수로 전달 된 요소의 순서를 임의로 재정렬합니다. 이것은 기본 크기가 전달 된 배열의 크기임을 의미합니다. 행 현명한 셔플을 수행하는 교체없이 샘플링이 수행되도록 매개 변수 replace=FALSE(기본값)를 전달 sample(...)합니다.

열 방향 섞기 :

> df3 <- df1[,sample(ncol(df1))]
> df3
  c a b
1 0 1 1
2 0 1 0
3 0 0 1
4 0 0 0

5
나는 이것이 최고의 댓글이 아니라는 것이 재미 있다고 생각하지만 다른 패키지에 대해 배우는 것보다 간단합니다. 순열에 대한 거의 모든 질문에 해당됩니다. SAMPLE () 만 사용하세요!
Brash Equilibrium

이 방법이 row.names를 유지한다고 가정하는 것이 맞습니까?
tumultous_rooster 2013

이 경우 = 표준 이상을 사용하는 이유는 무엇입니까?
Christian

4
음, 이것은 행과 열의 순서를 변경하고 있지만 OP가 원하는 것은 다릅니다. 각 열 / 행을 독립적으로
섞습니다

정확히 내가 필요한 것!
ChuckCottrill

18

이것은 data.frameusing 패키지 를 섞는 또 다른 방법입니다 dplyr.

행 방식 :

df2 <- slice(df1, sample(1:n()))

또는

df2 <- sample_frac(df1, 1L)

컬럼 방식 :

df2 <- select(df1, one_of(sample(names(df1)))) 

10

한 번 봐 가지고 permatswap()에서 채식 패키지를. 다음은 행 및 열 합계를 모두 유지하는 예입니다. 그러나이를 완화하고 행 또는 열 합계 중 하나만 수정할 수 있습니다.

mat <- matrix(c(1,1,0,0,0,0,0,1,1,0,0,0,1,1,1,0,1,0,1,1), ncol = 5)
set.seed(4)
out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")

이것은 다음을 제공합니다.

R> out$perm[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    1    1    1
[2,]    0    1    0    1    0
[3,]    0    0    0    1    1
[4,]    1    0    0    0    1
R> out$perm[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    0    1    1
[2,]    0    0    0    1    1
[3,]    1    0    0    1    0
[4,]    0    0    1    0    1

전화를 설명하려면 :

out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")
  1. times 원하는 무작위 행렬의 수입니다. 여기서 99
  2. burnin무작위 샘플 채취를 시작하기 전에 이루어진 스왑 횟수입니다. 이것은 우리가 각 무작위 행렬을 취하기 시작하기 전에 우리가 샘플링하는 행렬이 상당히 무작위가되도록합니다.
  3. thin모든 thin스왑을 무작위로 추첨한다고 말합니다.
  4. mtype = "prab" 매트릭스를 존재 / 부재, 즉 바이너리 0/1 데이터로 취급합니다.

몇 가지 유의해야 할 점은 열이나 행이 무작위 화되었음을 보장하지는 않지만 burnin충분히 길다면 그런 일이 발생할 가능성이 높습니다. 또한 필요한 것보다 더 많은 임의의 행렬을 그리고 모든 요구 사항과 일치하지 않는 행렬을 버릴 수 있습니다.

행당 변경 횟수가 달라야하는 요구 사항도 여기에서 다루지 않습니다. 다시 원하는 것보다 더 많은 행렬을 샘플링 한 다음이 요구 사항을 충족하지 않는 행렬은 버릴 수 있습니다.


6

randomizeMatrixR 패키지 의 함수 를 사용할 수도 있습니다.picante

예:

test <- matrix(c(1,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0),nrow=4,ncol=4)
> test
     [,1] [,2] [,3] [,4]
[1,]    1    0    1    0
[2,]    1    1    0    1
[3,]    0    0    0    0
[4,]    1    0    1    0

randomizeMatrix(test,null.model = "frequency",iterations = 1000)

     [,1] [,2] [,3] [,4]
[1,]    0    1    0    1
[2,]    1    0    0    0
[3,]    1    0    1    0
[4,]    1    0    1    0

randomizeMatrix(test,null.model = "richness",iterations = 1000)

     [,1] [,2] [,3] [,4]
[1,]    1    0    0    1
[2,]    1    1    0    1
[3,]    0    0    0    0
[4,]    1    0    1    0
> 

이 옵션 null.model="frequency"은 열 합계를 richness유지하고 행 합계를 유지합니다. 주로 커뮤니티 생태학에서 종 존재 부재 데이터 세트를 무작위 화하는 데 사용되지만 여기서는 잘 작동합니다.

이 함수에는 다른 null 모델 옵션도 있습니다. 문서 의 자세한 내용 (36 페이지)은 다음 링크를 확인하세요. picante


4

물론 각 행을 샘플링 할 수 있습니다.

sapply (1:4, function (row) df1[row,]<<-sample(df1[row,]))

행 자체를 셔플하므로 1각 행의 의 수가 변경되지 않습니다. 작은 변화와 열에서도 잘 작동하지만 이것은 독자를위한 연습입니다 :-P


2
OP가 부과하려는 제약을 구현하려는 시도는 없습니다.
Gavin Simpson

2

다음과 같이 데이터 프레임에서 동일한 수의 항목을 "샘플링"할 수도 있습니다.

nr<-dim(M)[1]
random_M = M[sample.int(nr),]

대신 dim(M)[1]사용할 nrow(M)수 있으므로 전체 절차가 한 줄짜리가됩니다.random_M <- M[nrow(M),]
Agile Bean

1

목표가 각 열을 무작위로 섞는 것이라면 열이 공동으로 섞여 있기 때문에 위의 답변 중 일부가 작동하지 않습니다 (이는 열 간 상관 관계를 유지함). 다른 것들은 패키지를 설치해야합니다. 그러나 한 줄짜리가 있습니다.

df2 = lapply(df1, function(x) { sample(x) })

0

데이터 프레임의 랜덤 샘플 및 순열 매트릭스 형태 인 경우 data.frame으로 변환 기본 패키지의 샘플 함수 사용 indexes = sample (1 : nrow (df1), size = 1 * nrow (df1)) Random Samples and Permutations

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.