Как это перебрать матрицу, используя функцию в R? - PullRequest
0 голосов
/ 07 февраля 2020

Я создал функцию для упорядочения вектора длины 2, используя следующий код

x = (c(6,2))
orders = function(x){
  for(i in 1:(length(x)-1)){
  if(x[i+1] < x[i]){
    return(c(x[i+1], x[i]))} else{
      (return(x))
  }}}


orders(x)

Меня попросили использовать эту функцию для обработки набора данных с 2 столбцами, как показано ниже. Выполните итерацию по строкам набора данных, и если элемент во 2-м столбце строки i меньше, чем элемент в первом столбце строки i , переключите порядок две записи в строке, сделав подходящий вызов функции, которую вы только что написали.

Я попытался использовать следующий код

set.seed(1128719)
data=matrix(rnorm(20),byrow=T,ncol=2)
df = for (i in 1:2) {
  for(j in 1:10){
    data = orders(c(x[i], x[j]))
    return(data)
  }

}

Вывод равен нулю. Я не совсем уверен, где я иду не так. Есть предложения?

Ответы [ 2 ]

2 голосов
/ 07 февраля 2020

Вот два способа упорядочить матрицу из 2 столбцов.

Это тестовая матрица, размещенная в вопросе.

set.seed(1128719)
data <- matrix(rnorm(20), byrow = TRUE, ncol = 2)

1. С функцией orders.

Функция ожидает в качестве входного вектора 2 элемента. Если они не в порядке, верните вектор с обращенными элементами, иначе верните вектор как есть.

orders <- function(x){
  stopifnot(length(x) == 2)
  if(x[2] < x[1]){
    x[2:1]
  }else{
    x
  }
}

Проверьте функцию.

x <- c(6,2)
orders(x)
#[1] 2 6

Теперь с матрицей data.

df1 <- t(apply(data, 1, orders))

2. Векторизованный код.

Создает логический индекс с TRUE всякий раз, когда элементы вышли из строя и обращают только эти элементы в обратном порядке.

df2 <- data
inx <- data[,2] < data[,1]
df2[inx, ] <- data[inx, 2:1]

Результаты совпадают.

identical(df1, df2)
#[1] TRUE
2 голосов
/ 07 февраля 2020

Я немного изменил ваш код, но попытался сохранить тот же «стиль». Нет необходимости в цикле i in 1:(length(x)-1) всегда оценивается как for i in 1:1, а i будет принимать значение только 1.

orders = function(x){

      # Since the function will only work on vectors of length 2
      # its good practice to raise an error right at the start
      #   
      if (length(x) != 2) {
        stop("x must be vector of lenght 2")
      } 

  if (x[2] < x[1]) {
    return(c(x[2], x[1]))
  } else {
    return(x)
  }
}

orders(c(6, 2))


set.seed(1128719)
data <- matrix(rnorm(20),byrow=T,ncol=2)

Саму переменную l oop нельзя присвоить переменной, но мы используем l oop для изменения матрицы 'data' на месте

for (row in 1:nrow(data)) {
  data[row, ] <- orders(data[row,])
}

data

Редактировать:

Это ввод:

            [,1]        [,2]
[1,] -0.04142965  0.2377140
[2,] -0.76237866 -0.8004284
[3,]  0.18700893 -0.6800310
[4,]  0.76499646  0.4430643
[5,]  0.09193440 -0.2592316
[6,]  1.17478053 -0.4044760
[7,] -1.62262500  0.1652850
[8,] -1.54848857  0.7475451
[9,] -0.05907252 -0.8324074
[10,] -1.11064318 -0.1148806

Это вывод, который я получаю:

            [,1]        [,2]
[1,] -0.04142965  0.23771403
[2,] -0.80042842 -0.76237866
[3,] -0.68003104  0.18700893
[4,]  0.44306433  0.76499646
[5,] -0.25923164  0.09193440
[6,] -0.40447603  1.17478053
[7,] -1.62262500  0.16528496
[8,] -1.54848857  0.74754509
[9,] -0.83240742 -0.05907252
[10,] -1.11064318 -0.11488062
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...