функция не обрабатывает входной аргумент в R - PullRequest
0 голосов
/ 07 мая 2020

У меня есть набор данных, состоящий из 82 столбцов.

Я пытаюсь написать функцию, которая принимает имя столбца в качестве аргумента (x), а затем преобразует имена в этом столбце в число. Количество уникальных имен для каждого столбца различается.

образец данных:

df <- data.frame(column_1 = 1:10, column_2 = c("MT", "BM", "KA", "MT", "BM", "KA","MT", "BM", "KA", "MT"))

Я ожидал, что эта функция преобразует столбец_2 в:

1,2,3 , 1,2,3,1,2,3,1

Когда я тестировал тело функции, оно делает то, что должно: 1) применять функцию только тогда, когда это символ и есть не являются NA 2) выберите уникальные значения 3) замените это уникальное значение числом от 1 до n

UniekeNamen <- unique(VolledigeSet$MSZoning)
VervangenVoor <- c(1:length(VolledigeSet$MSZoning))
if (is.character(VolledigeSet$MSZoning) & sum(is.na(VolledigeSet$MSZoning) == 0)) {
  for (i in seq_along(UniekeNamen)) {
    VolledigeSet$MSZoning[VolledigeSet$MSZoning == UniekeNamen[i]] <- VervangenVoor[i]
  }
}

Но когда я заключаю тело в функцию и заменяю имя столбца на аргумент x функция не работает, как если бы аргумент не распознавался. Нет сообщения об ошибке, просто ничего не происходит ...

Это функция, которую я написал:

name2num <- function(x) {
  UniekeNamen <- unique(x)
  VervangenVoor <- c(1:length(UniekeNamen))
  if (is.character(x) & sum(is.na(x) == 0)) {
   for (i in seq_along(UniekeNamen)) {
     x[x == UniekeNamen[i]] <- VervangenVoor[i]
   }
  }
}

У вас есть предложение, что изменить в функции?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 07 мая 2020

Вы должны вернуть вектор вывода, который, в свою очередь, нужно применить к существующему набору данных путем замены.

name2num <- function(x) {
  UniekeNamen <- unique(x)
  VervangenVoor <- c(1:length(UniekeNamen))
  if (is.character(x) !=0 & sum(is.na(x) == 0)) {
    for (i in seq_along(UniekeNamen)) {
      x[x == UniekeNamen[i]] <- VervangenVoor[i]
    }
    return(as.factor(x))
  }
}


df$column_2 <- name2num(df$column_2)
df 

Вывод:

   column_1 column_2
1         1        1
2         2        2
3         3        3
4         4        1
5         5        2
6         6        3
7         7        1
8         8        2
9         9        3
10       10        1

PS: Если вы хотите иметь column_2 как numeri c, используйте return(as.numeric(x)) вместо

0 голосов
/ 07 мая 2020

Ваша основная проблема в том, что ваша функция должна return полностью модифицировать x. Вы можете сделать это, поместив x или return(x) в качестве последней строки функции.

Когда я исправляю проблему возврата и запускаю функцию с вашими образцами данных, df$column_2 не изменяется, потому что этот столбец фактор, а не символ (поскольку я еще не обновился до R 4.0), поэтому я демонстрирую, что он приводит column_2 к персонажу.

Это даст нам эту функцию:

name2num <- function(x) {
  UniekeNamen <- unique(x)
  VervangenVoor <- c(1:length(UniekeNamen))
  if (is.character(x) & sum(is.na(x) == 0)) {
   for (i in seq_along(UniekeNamen)) {
     x[x == UniekeNamen[i]] <- VervangenVoor[i]
   }
  }
  x
}

name2num(as.character(df$column_2))
# [1] "1" "2" "3" "1" "2" "3" "1" "2" "3" "1"

Обратите внимание: поскольку элементы столбца меняются по очереди, класс столбца остается прежним. Если вы хотите, чтобы на выходе было число c, а не символ, у вас должна быть функция return as.numeric(x).

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

name2num_gt = function(x) {
  if ((is.character(x) | is.factor(x)) & sum(is.na(x) == 0)) {
    x = as.integer(factor(x, levels = unique(x)))
  }
  x
}
name2num_gt(as.character(df$column_2))
# [1] 1 2 3 1 2 3 1 2 3 1

Есть много способов применить это ко всем столбцам ваших данных. Один из вариантов - df[] = lapply(df, name2num_gt).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...