根据另一列中的因子级别更改一列中的数值

时间:2014-09-18 02:56:02

标签: r if-statement dataframe

我需要将数据框的一列中的某些数值设置为零,如果在另一列中它们具有某个因子级别。

我的数据框df看起来像:

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

对于Store.Type =" A"的所有行,我想做的是make Items = 0。或" C"

我对R很新,但认为这将是形式的条件陈述"如果Store.Type A则是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是一个控制流语句,将单个逻辑值作为参数
  •   
  • ifelse是一个向量化函数,以向量作为其所有参数。
  •   

因此,我需要ifelse来完成整个专栏并能够理解?ifelse页面,我尝试了#34;如果Store.Type A然后是项目&lt; - 0其他什么都不做&#34;。事实上我希望它嵌套,所以我尝试了以下代码(现在创建一个新列,所以我不会弄乱我的数据,但最终会覆盖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添加任何内容,它只会写入正确的值。我尝试将ItemsItems <- Items放入&#34;否则将项目保留为项目&#34;如下所示,但这只是将一切都改为零。

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

有没有办法告诉ifelse什么都不做,或者有更简单的方法吗?

5 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分: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结合使用时更是如此,并且可能总是比矢量化方法更慢。

答案 3 :(得分: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

答案 4 :(得分:0)

这是解决问题的最佳方式

  

df $ Items [which(df $ store.type == 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