Замена значений столбцов во фрейме данных, не включенных в список - PullRequest
2 голосов
/ 19 октября 2011

У меня есть data.frame в R, например:

fruits
   X1  X2     X3
   aa  kiwi  15
   ba  orange 25
   cc  lemon  23
   ba  apple  17
   cc  lemon  19
   cc  orange  18
   cc  orange 21
   ba  banana  17

Я бы хотел заменить все значения в столбце X2, кроме "orange" и "lemon" на "other". Как это сделать в R?

Пример данных:

fruits <- structure(list(X1 = structure(c(1L, 2L, 3L, 2L, 3L, 3L, 3L, 2L
), .Label = c("aa", "ba", "cc"), class = "factor"), X2 = structure(c(3L, 
5L, 4L, 1L, 4L, 5L, 5L, 2L), .Label = c("apple", "banana", "kiwi", 
"lemon", "orange"), class = "factor"), X3 = c(15L, 25L, 23L, 
17L, 19L, 18L, 21L, 17L)), .Names = c("X1", "X2", "X3"), class = "data.frame", row.names = c(NA, 
-8L))

Ответы [ 3 ]

5 голосов
/ 19 октября 2011

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

shouldBecomeOther<-!(fruits$X2 %in% c("orange", "lemon"))

Затем используйте этот индексатор:

fruits$X2[shouldBecomeOther]<- "other"

Обратите внимание, что если столбец является фактором (весьма вероятным), потребуется еще немного работы, например:

tmp<-as.character(fruits$x2)
tmp[shouldBecomeOther]<-"other"
fruits$x2<-factor(tmp)
2 голосов
/ 19 октября 2011

Простой способ - привести фактор к вектору символов, затем определить, какие элементы не входят в требуемые классы, заменить их на "other" и, наконец, привести к фактору.

В этой теме есть два варианта, первый из которых использует функцию replace():

transform(fruits,
          X2 = factor(replace(as.character(X2), 
                              list = !X2 %in% c("orange","lemon"),
                              values = "other")))

, что дает:

> transform(fruits, X2 = factor(replace(as.character(X2), 
+                                       list = !X2 %in% c("orange","lemon"),
+                                       values = "other")))
  X1     X2 X3
1 aa  other 15
2 ba orange 25
3 cc  lemon 23
4 ba  other 17
5 cc  lemon 19
6 cc orange 18
7 cc orange 21
8 ba  other 17

Или вы можете сделать это вручную:

fruits <- transform(fruits, 
                    X2 = {x <- as.character(X2)
                          x[!x %in% c("orange","lemon")] <- "other"
                          factor(x)})
> fruits
  X1     X2 X3
1 aa  other 15
2 ba orange 25
3 cc  lemon 23
4 ba  other 17
5 cc  lemon 19
6 cc orange 18
7 cc orange 21
8 ba  other 17

Я использую transform() здесь, чтобы мы выполняли манипуляции внутри среды, где X2 видим, без необходимости использовать такие вещи, как fruits$X2, что утомительно печатать.

1 голос
/ 19 октября 2011

А как же:

R> fruits = data.frame(X1 = 1:3, X2 = c("kiwi", "orange", "lemon"))
R> fruits$X2 = as.character(fruits$X2)
R> fruits[!(fruits$X2 %in% c("lemon", "orange")),]$X2 = "Other"
R> fruits
  X1     X2
1  1  Other
2  2 orange
3  3  lemon

В приведенном выше решении я преобразовал факторы в «символы». Вам не нужно этого делать, вы также можете:

  1. При создании фрейма данных используйте аргумент stringsAsFactors = FALSE
  2. Если вы используете read.csv, используйте stringsAsFactors
  3. Вы работаете с факторами напрямую:

    R> fruits$X2 = factor(fruits$X2, levels = c(as.character(fruits$X2), "Other"))
    R> fruits[!(fruits$X2 %in% c("lemon", "orange")),]$X2 = "Other"
    R> fruits
      X1     X2
    1  1  Other
    2  2 orange
    3  3  lemon
    

    Обратите внимание, что я расширяю уровни первого фактора в строке 1.

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