Как добавить столбец в фрейм данных в R - PullRequest
6 голосов
/ 30 декабря 2010

Я импортировал данные из файла во фрейм данных в R. Это что-то вроде этого.

Name      Count   Category
A         100     Cat1
C         10      Cat2
D         40      Cat1 
E         30      Cat3
H         3       Cat3
Z         20      Cat2
M         50      Cat10

Итак, теперь я хочу добавить столбец Категория в зависимости от значений в столбце Имя . Так что, например, если Name = (A, D), Category = 'Cat1' и т. Д.

Это всего лишь простой пример, который я привожу. У меня есть большое количество имен и категорий, поэтому я хочу компактный синтаксис. Как я могу это сделать?

Редактировать: я изменил пример, чтобы лучше соответствовать моим потребностям, поскольку имя может быть любым, не числовым. Извините за то, что не слишком ясно, прежде чем.

Ответы [ 5 ]

3 голосов
/ 30 декабря 2010

Вы можете использовать ifelse. Если бы ваш фрейм данных назывался df, вы бы сделали:

df$cat <- ifelse(df$name<100, "Ones", "Hundreds")
df$cat <- ifelse(df$name<1000, df$cat, "Thousands")
2 голосов
/ 30 декабря 2010

[Обновить после комментария ОП и изменить Q]

DF <- data.frame(Name = c("A","C","D","E","H","Z","M"),
                 Count = c(100,10,40,30,3,20,50), stringsAsFactors = FALSE)
lookup <- data.frame(Name = c("A","C","D","E","H","Z","M"),
                     Category = paste("Cat", c(1,2,1,3,3,2,10), sep = ""),
                     stringsAsFactors = FALSE)

Используя вышеупомянутые фреймы данных, мы можем выполнить слияние базы данных. Вам нужно настроить lookup для нужных комбинаций Name Category, что нормально, если не очень большое количество Name с (по крайней мере, вам нужно перечислить их только один раз в lookup и вам не нужно делать это по порядку - сначала перечислите все Cat1 Name с и т. Д.):

> merge(DF, lookup, by = "Name")
  Name Count Category
1    A   100     Cat1
2    C    10     Cat2
3    D    40     Cat1
4    E    30     Cat3
5    H     3     Cat3
6    M    50    Cat10
7    Z    20     Cat2
> merge(DF, lookup, by = "Name", sort = FALSE)
  Name Count Category
1    A   100     Cat1
2    C    10     Cat2
3    D    40     Cat1
4    E    30     Cat3
5    H     3     Cat3
6    Z    20     Cat2
7    M    50    Cat10

Один из вариантов индексации:

foo <- function(x) {
    out <- character(length = length(x))
    chars <- c("Ones", "Tens", "Hundreds", "Thousands")
    out[x < 10] <- chars[1]
    out[x >= 10 & x < 100] <- chars[2]
    out[x >= 100 & x < 1000] <- chars[3]
    out[x >= 1000 & x < 10000] <- chars[4]
    return(factor(out, levels = chars))
}

Альтернатива, которая лучше масштабируется:

bar <- function(x, cats = c("Ones", "Tens", "Hundreds", "Thousands")) {
    out <- cats[floor(log10(x)) + 1]
    factor(out, levels = cats)
}
2 голосов
/ 30 декабря 2010

Вы можете использовать карту.(ОБНОВЛЕНО для использования stringsAsFactors = FALSE)

df <- data.frame( Name = c('A', 'C', 'D', 'E', 'H', 'Z', 'M'), 
                  Count = c(100,10,40,30,3,20,50), stringsAsFactors = FALSE)
Categories <- list(Cat1 = c('A','D'), 
                   Cat2 = c('C','Z'), 
                   Cat3 = c('E','H'), 
                   Cat10 = 'M')
nams <- names( Categories )
nums <- sapply(Categories, length)
CatMap <- unlist( Map( rep, nams, nums ) )
names(CatMap) <- unlist( Categories )

df <- transform( df, Category = CatMap[ Name ])
0 голосов
/ 24 октября 2013

Возможно, проще и удобочитаемее, используя ifelse и% в%:

df <- data.frame( Name = c('A', 'C', 'D', 'E', 'H', 'Z', 'M'), 
Count =c(100,10,40,30,3,20,50), stringsAsFactors = FALSE)

cat1 = c("A","D")
cat2 = c("C","Z")
cat3 = c("E","H")
cat10 = c("M")

df$Category = ifelse(df$Name %in% cat1, "Cat1",
              ifelse(df$Name %in% cat2, "Cat2",
              ifelse(df$Name %in% cat3, "Cat3",
              ifelse(df$Name %in% cat10, "Cat10",
              NA))))

   Name Count Category
1    A   100     Cat1
2    C    10     Cat2
3    D    40     Cat1
4    E    30     Cat3
5    H     3     Cat3
6    Z    20     Cat2
7    M    50    Cat10
0 голосов
/ 01 января 2011

оформить заказ:

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