在矩阵中采样列值,无需替换

时间:2013-02-01 16:51:28

标签: r

我对R有一些经验,但总是很难编写新代码。我在处理当前项目时发现了一些非常有用的帖子,但似乎无法找到下一步。这是我到目前为止所做的:

  • 输入了20x20 .csv的排名;每列包含1到20之间的每个整数的一个实例,因此所有colSums都是210. rowSums不同。

  • 在这里使用一个帖子从原始矩阵中随机抽取4行并将它们放入一个新的4x20矩阵中。

现在,我需要从每行中抽取5列,而无需替换列。也就是说,我需要每列只使用一次并且每行有五个值。 (我不喜欢这是否给了我一个在正确位置有20个值的矩阵和60个零,或者如果我得到4个5值的向量。我想我有点想要矩阵?)

如果上下文有帮助,我会尝试根据教室中的主​​题排名创建群组。行是主题,列是选民(学生)。最终我想在for循环中创建这些随机分配,并多次运行程序以希望自动优化选择(通过一些测量;显然有不同的优化方法)而不是通过盯着原始矩阵,这是什么我过去做过。

这是我的4x20矩阵:

    J  E  I  S  A  N  H  T  M  B  D  K  O  G  P  L  Q  R  F  C
2   5  4  1  1  5 13  3  4 13 11 14 14 20  9 15  9 11 17  9 15
13 20 19 17 19 19  7  4 19  7  1  5  1 17 15 10  6  7 14  6  3
14 18  2 12 14 11 19 18 15 19  4  8 19  2  2 13  7  9  1 12 10
18  4  7 18  5 12 18  2 20  6  7 16 15  5 18  1 13  2 18 14 16

这是我想要的(一个版本):

    J  E  I  S  A  N  H  T  M  B  D  K  O  G  P  L  Q  R  F  C
2   0  4  1  1  0  0  3  4  0  0  0  0  0  0  0  0  0  0  0  0
13  0  0  0  0  0  7  0  0  0  1  5  1  0  0  0  0  0  0  0  3
14  0  0  0  0 11  0  0  0  0  0  0  0  0  2  0  7  0  1 12  0
18  4  0  0  0  0  0  0  0  6  0  0  0  5  0  1  0  2  0  0  0

4 个答案:

答案 0 :(得分:7)

您可以使用apply。以下命令将从每行中随机抽取五个值并返回结果矩阵:

apply(mat, 1, sample, 5)

您可能希望将返回的矩阵转换为t以匹配原始矩阵。


如果只想使用每一列,可以使用以下命令:

mat[cbind(seq(nrow(mat)), sample(ncol(mat), 5 * nrow(mat)))]

它将返回包含值的矢量。

要匹配所需的输出格式(矩阵包括零和随机选择的值),您可以使用以下策略:

# create an index of the values to be kept
idx <- cbind(seq(nrow(mat)), sample(ncol(mat), 5 * nrow(mat)))

# create a new matrix of zeroes
mat2 <- matrix(0, ncol = ncol(mat), nrow = nrow(mat))

# copy the values from the original matrix to the new one
mat2[idx] <- mat[idx]

答案 1 :(得分:1)

这应该有效

data <- matrix(sample(letters,20*4,rep=T),4) # Create a fake data

sample <- sample(1:20) # Scramble the order of the columns

out <- matrix(0,4,5) # 5 letters for 4 lines

for (i in 1:4) {
 out[i,] <- data[i,sample[1:5 + (i-1)*5]] # Sample 5 values of each line
}

答案 2 :(得分:1)

假设您的data.frame被称为“x”,这是一种简单的方法,可以产生list单行data.frame

这是您的数据:

x <- structure(list(J = c(5L, 20L, 18L, 4L), E = c(4L, 19L, 2L, 7L
  ), I = c(1L, 17L, 12L, 18L), S = c(1L, 19L, 14L, 5L), A = c(5L, 
  19L, 11L, 12L), N = c(13L, 7L, 19L, 18L), H = c(3L, 4L, 18L, 
  2L), T = c(4L, 19L, 15L, 20L), M = c(13L, 7L, 19L, 6L), B = c(11L, 
  1L, 4L, 7L), D = c(14L, 5L, 8L, 16L), K = c(14L, 1L, 19L, 15L
  ), O = c(20L, 17L, 2L, 5L), G = c(9L, 15L, 2L, 18L), P = c(15L, 
  10L, 13L, 1L), L = c(9L, 6L, 7L, 13L), Q = c(11L, 7L, 9L, 2L), 
      R = c(17L, 14L, 1L, 18L), F = c(9L, 6L, 12L, 14L), C = c(15L, 
      3L, 10L, 16L)), .Names = c("J", "E", "I", "S", "A", "N", 
  "H", "T", "M", "B", "D", "K", "O", "G", "P", "L", "Q", "R", "F", 
  "C"), class = "data.frame", row.names = c("2", "13", "14", "18"
  ))

抽样:

set.seed(1)
temp <- matrix(sample(20), nrow = 4)
do.call(rbind, lapply(1:4, function(y) {
  x[y, -temp[y, ]] <- 0
  x[y, ]
}))
#     J E  I S  A  N H  T M B D  K O  G  P  L Q R F  C
# 2   0 0  0 1  0 13 0  0 0 0 0 14 0  0  0  0 0 0 9 15
# 13 20 0  0 0  0  0 0 19 0 1 0  0 0 15  0  0 7 0 0  0
# 14  0 0 12 0 11  0 0  0 0 0 8  0 0  0 13  0 0 1 0  0
# 18  0 7  0 0  0  0 2  0 6 0 0  0 5  0  0 13 0 0 0  0

答案 3 :(得分:1)

使用Matrix包,我们可以很容易地从索引构建它:

i <- sample(nrow(X), ncol(X), replace=TRUE)
j <- seq(ncol(X))
sparseMatrix(i,j,x=X[cbind(i,j)])

的产率:

> sparseMatrix(i,j,x=X[cbind(i,j)])
4 x 20 sparse Matrix of class "dgCMatrix"

[1,] . .  .  .  . 13 .  . 13 . 14  . . 9  .  . .  . . 15
[2,] . .  .  .  .  . .  .  . .  .  . . .  .  . .  . 6  .
[3,] . .  . 14 11  . . 15  . 4  . 19 2 . 13  . .  . .  .
[4,] 4 7 18  .  .  . 2  .  . .  .  . . .  . 13 2 18 .  .