【问题标题】:Change numeric values in one column based on factor levels in another column根据另一列中的因子水平更改一列中的数值
【发布时间】:2014-11-12 06:00:13
【问题描述】:

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

我的数据框 df 看起来像:

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

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

我对 R 很陌生,但我认为这将是“If Store.Type A then Items ?"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 页面,我尝试执行“如果 Store.Type A 则 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 &lt;- Items 放入如下所示的“否则将项目保留为项目”,但这只是将所有内容都更改为零。

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

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

【问题讨论】:

  • df$Items[which(df$Store.Type == "A" | df$Store.Type == "C" )] &lt;- 0
  • 即找到需要更改的行,然后将这些条目设置为 0。
  • 感谢大家提供这些解决方案,它们确实都有效,但我还不确定如何/为什么!我认为which%in% 似乎是我应该研究的最简单的。
  • 哦,@Alex 我会投票给你的答案,但我不知道如何,因为它在评论中......

标签: r if-statement dataframe


【解决方案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 进行子集化,我们可以将它们替换为[&lt;-

另外,如果你想使用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 结合使用时更是如此,并且可能总是比顶部的矢量化方法慢。

【讨论】:

    【解决方案2】:

    或者您可以使用%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
    

    【讨论】:

      【解决方案3】:

      以下也有效:

      > 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】:

        使用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
        

        【讨论】:

          【解决方案5】:

          这是最好的解决办法

          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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-04-15
            相关资源
            最近更新 更多