2014-09-18 3 views
5

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

Мой dataframe ДФ выглядит что-то вроде:

Items Store.Type 
5  A 
4  B 
3  C 
6  D 
3  B 
7  E 

То, что я хочу сделать, это Items = 0, для всех строк, где Store.Type = "A" или "C"

I» m очень новый для R, но решил, что это будет условным выражением формы «If Store.Type A then Items < - 0» (а затем повторите для Store.Type C), но я не понял страницу ?"if" вообще. Я пробовал:

df$ItemsFIXED <- with(df, if(Store.Type == "A")Items <-0) 

и получил предупреждение:

Warning message: 
In if (Store.Type2 == "Chain - Brand") Total.generic.items <- 0 : 
the condition has length > 1 and only the first element will be used` 

Так что я заметил here следующее:

  • if is a control flow statement, taking a single logical value as an argument
  • ifelse is a vectorised function, taking vectors as all its arguments.

Так выясняя мне нужно ifelse сделать весь столбец и быть способный понять страницу ?ifelse, я попытался сделать «Если Store.Type A, то Items < - 0 else ничего не делать». На самом деле я хотел его вложенным, поэтому я попытался следующий код (создать новый столбец сейчас, так что я не испортили мои данные, но в конечном счете это приведет к перезаписи данных Items)

df$ItemsFIXED <- with(df, ifelse(Store.Type == "A", Items <-0, 
          ifelse(Store.Type == "C", Items <-0,))) 

и получил следующее ошибка:

Error in ifelse(Store.Type2 == "Franchise - Brand", Total.generic.items <- 0, : 
    argument "no" is missing, with no default 

Но если я надену что-нибудь в течение no он просто записывает над значениями, которые являются правильными. Я попробовал поставить Items и Items <- Items, чтобы сказать «else leave Items as Items», как в следующем, но это просто изменило все на ноль.

df$ItemsFIXED <- with(df, ifelse(Store.Type == "A", Items <-0, 
          ifelse(Store.Type == "C", Items <-0,Items))) 

Есть ли способ сказать ifelse ничего не делать, или есть более простой способ сделать это?

+1

'DF $ Элементы [которые (df $ Store.Type == "A" | df $ Store.Type == "C")] <- 0' – Alex

+0

т.е. найдите строки, которые нужно изменить, затем установите эти записи на 0. – Alex

+0

Спасибо всем за эти решения, они действительно работают, но я не совсем уверен, как и почему еще! Я думаю, что 'which' и'% in% 'кажутся простейшими, что я должен изучить больше. – JenLouise

ответ

5

Или вы могли бы использовать %in% для многократных матча/замен

df$Items[df$Store.Type %in% c("A", "C")] <- 0 
    df 
    #Items Store.Type 
    #1  0   A 
    #2  4   B 
    #3  0   C 
    #4  6   D 
    #5  3   B 
    #6  7   E 
1

Здесь вы можете воспользоваться векторизованной заменой. Если df это набор данных,

> df$Items[with(df, Store.Type == "A" | Store.Type == "C")] <- 0L 
> df 
# Items Store.Type 
# 1  0   A 
# 2  4   B 
# 3  0   C 
# 4  6   D 
# 5  3   B 
# 6  7   E 

with(df, Store.Type == "A" | Store.Type == "C") возвращает логический вектор. Когда логический вектор помещается внутри [...], возвращаются только значения TRUE. Так что, если мы Подмножество Items с этими значениями, мы можем заменить их [<-

Кроме того, если вы хотите использовать ifelse, вы могли бы сделать что-то вроде

df$Items <- with(df, ifelse(Store.Type == "A" | Store.Type == "C", 0L, Items)) 

или

within(df, Items <- ifelse(Store.Type == "A" | Store.Type == "C", 0L, Items)) 

но взять обратите внимание, что ifelse может быть очень медленным время от времени, тем более в сочетании с within и, вероятно, всегда будет медленнее, чем векторный метод вверх.

1

также следующих работы:

> ddf[ddf$Store.Type=='A'| ddf$Store.Type=='C',]$Items = 0 
> ddf 
    Items Store.Type 
1  0   A 
2  4   B 
3  0   C 
4  6   D 
5  3   B 
6  7   E 
2

Использования within, кажется, тоже вариант:

within(d, Items[Store.Type %in% c("A","C")]<-0) 

    Items Store.Type 
1  0   A 
2  4   B 
3  0   C 
4  6   D 
5  3   B 
6  7   E 
+0

+1 Выглядит хорошо, никогда не пробовал. – akrun

Смежные вопросы