ProgramingTip

R에서 벡터의 요소로 많은 행을 나누는 방법

bestdevel 2021. 1. 6. 20:52
반응형

R에서 벡터의 요소로 많은 행을 나누는 방법


의 행렬 을 고정 벡터 로 나누고 싶습니다 . 예를 들면

mat<-matrix(1,ncol=2,nrow=2,TRUE)
dev<-c(5,10)

[해석]주는 mat/devdev.

     [,1] [,2]
[1,]  0.2  0.2
[2,]  0.1  0.1

그러나 결과적으로 원하는 것을 원합니다. 즉, 행 단위로 작업을 수행하십시오 .

rbind(mat[1,]/dev, mat[2,]/dev)

     [,1] [,2]
[1,]  0.2  0.1
[2,]  0.2  0.1

도달하는 명시적인 명령이 있습니까?


다음은 코드 길이를 늘리는 몇 가지 방법입니다.

t(t(mat) / dev)

mat / dev[col(mat)] #  @DavidArenburg & @akrun

mat %*% diag(1 / dev)

sweep(mat, 2, dev, "/")

t(apply(mat, 1, "/", dev))

plyr::aaply(mat, 1, "/", dev)

mat / rep(dev, each = nrow(mat))

mat / t(replace(t(mat), TRUE, dev))

mapply("/", as.data.frame(mat), dev)  # added later

mat / matrix(dev, nrow(mat), ncol(mat), byrow = TRUE)  # added later

do.call(rbind, lapply(as.data.frame(t(mat)), "/", dev))

mat2 <- mat; for(i in seq_len(nrow(mat2))) mat2[i, ] <- mat2[i, ] / dev

데이터 프레임

로 시작하는 모든 솔루션 은 데이터 프레임 인 경우 mat /에도 작동 mat및 데이터 프레임 결과를 생성합니다. sweep솔루션과 마지막 솔루션 의 경우도 마찬가지입니다 mat2. mapply솔루션은 data.frames와 함께 작동하지만 매트릭스를 생성합니다.

벡터

mat이 아닌 또는 일반 행렬 벡터 인 경우 이들 중 하나는 하나의 열 행렬을 반환합니다.

t(t(mat) / dev)
mat / t(replace(t(mat), TRUE, dev))

그리고 이것은 벡터를 반환합니다.

plyr::aaply(mat, 1, "/", dev)

나머지는 오류, 경고 또는 원하는 대답이 아닙니다.

벤치 마크

코드의 간결함과 명확성이보다 더 중요 할 수있는 속도를 위해 여기에 10 번 반복 한 다음 100 번 반복하는 몇 가지 벤치 마크가 있습니다.

library(microbenchmark)
library(plyr)

set.seed(84789)

mat<-matrix(runif(1e6),nrow=1e5)
dev<-runif(10)

microbenchmark(times=10L,
  "1" = t(t(mat) / dev),
  "2" = mat %*% diag(1/dev),
  "3" = sweep(mat, 2, dev, "/"),
  "4" = t(apply(mat, 1, "/", dev)),
  "5" = mat / rep(dev, each = nrow(mat)),
  "6" = mat / t(replace(t(mat), TRUE, dev)),
  "7" = aaply(mat, 1, "/", dev),
  "8" = do.call(rbind, lapply(as.data.frame(t(mat)), "/", dev)),
  "9" = {mat2 <- mat; for(i in seq_len(nrow(mat2))) mat2[i, ] <- mat2[i, ] / dev},
 "10" = mat/dev[col(mat)])

기부 :

Unit: milliseconds
 expr         min          lq       mean      median          uq        max neval
    1    7.957253    8.136799   44.13317    8.370418    8.597972  366.24246    10
    2    4.678240    4.693771   10.11320    4.708153    4.720309   58.79537    10
    3   15.594488   15.691104   16.38740   15.843637   16.559956   19.98246    10
    4   96.616547  104.743737  124.94650  117.272493  134.852009  177.96882    10
    5   17.631848   17.654821   18.98646   18.295586   20.120382   21.30338    10
    6   19.097557   19.365944   27.78814   20.126037   43.322090   48.76881    10
    7 8279.428898 8496.131747 8631.02530 8644.798642 8741.748155 9194.66980    10
    8  509.528218  524.251103  570.81573  545.627522  568.929481  821.17562    10
    9  161.240680  177.282664  188.30452  186.235811  193.250346  242.45495    10
   10    7.713448    7.815545   11.86550    7.965811    8.807754   45.87518    10

100 회 반복으로 20 밀리 초 통화가 모든 테스트를 다시 실행합니다.

microbenchmark(times=100L,
  "1" = t(t(mat) / dev),
  "2" = mat %*% diag(1/dev),
  "3" = sweep(mat, 2, dev, "/"),
  "5" = mat / rep(dev, each = nrow(mat)),
  "6" = mat / t(replace(t(mat), TRUE, dev)),
 "10" = mat/dev[col(mat)])

기부 :

Unit: milliseconds
 expr       min        lq      mean    median        uq       max neval
    1  8.010749  8.188459 13.972445  8.560578 10.197650 299.80328   100
    2  4.672902  4.734321  5.802965  4.769501  4.985402  20.89999   100
    3 15.224121 15.428518 18.707554 15.836116 17.064866  42.54882   100
    5 17.625347 17.678850 21.464804 17.847698 18.209404 303.27342   100
    6 19.158946 19.361413 22.907115 19.772479 21.142961  38.77585   100
   10  7.754911  7.939305  9.971388  8.010871  8.324860  25.65829   100

따라서이 두 테스트에서 # 2 (사용 diag)가 가장 많이 사용합니다. 그 이유는 BLAS에 대한 거의 같은 호소에있을 수 있습니다 # 1은 비용이 많이 많이 사용 t됩니다.


apply행에있는 함수를 찾고 있습니다.

t(apply(mat, 1, function(x) x/dev))

참조 URL : https://stackoverflow.com/questions/20596433/how-to-divide-each-row-of-a-matrix-by-elements-of-a-vector-in-r

반응형