【问题标题】:R - How to apply different functions to certain rows in a columnR - 如何将不同的功能应用于列中的某些行
【发布时间】:2013-02-02 23:10:48
【问题描述】:

我正在尝试根据相邻列中字符串的值将不同的函数应用于不同的行。我的数据框如下所示:

type    size
A       1
B       3
A       4
C       2
C       5
A       4
B       32
C       3

我想将不同的函数应用于类型 A、B 和 C,以提供第三列“size2”。例如,假设以下函数适用于 A、B 和 C:

for A: size2 = 3*size
for B: size2 = size
for C: size2 = 2*size 

我可以使用此代码分别为每种类型执行此操作

df$size2 <- ifelse(df$type == "A", 3*df$size, NA)
df$size2 <- ifelse(df$type == "B", 1*df$size, NA)
df$size2 <- ifelse(df$type == "C", 2*df$size, NA)

但是,如果不删除所有其他值,我似乎无法对所有类型都执行此操作。我尝试使用此代码将函数的应用限制为仅适用于 NA 的值(即保留现有值并仅填写 NA 值),但使用此代码不起作用:

df$size2 <- ifelse(is.na(df$size2), ifelse(df$type == "C", 2*df$size, NA), NA)

有人有什么想法吗?是否可以在“is.na(df$size2)”和“ifelse(df$type == "C"" 中使用某种 AND 语句?

非常感谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    这可能更像是一个 R-ish(我将我的数据框称为“dat”而不是“df”,因为df 是一个常用函数。

    > facs <- c(3,1,2)
    > dat$size2= dat$size* facs[ match( dat$type, c("A","B","C") ) ]
    > dat
      type size size2
    1    A    1     3
    2    B    3     3
    3    A    4    12
    4    C    2     4
    5    C    5    10
    6    A    4    12
    7    B   32    32
    8    C    3     6
    

    match 函数用于构造索引以提供给提取函数[

    【讨论】:

      【解决方案2】:

      如果你愿意,你可以嵌套ifelses:

      df$size2 <- ifelse(df$type == "A", 3*df$size,
                             ifelse(df$type == "B", 1*df$size,
                                 ifelse(df$type == "C", 2*df$size, NA)))
      
      
      #    > df
      #  type size size2
      #1    A    1     3
      #2    B    3     3
      #3    A    4    12
      #4    C    2     4
      #5    C    5    10
      #6    A    4    12
      #7    B   32    32
      #8    C    3     6
      

      【讨论】:

      • 这行得通,但有点乏味,因为我有 32 种不同的“类型”LOL
      • 我提供了一种更紧凑的方法。如果嵌套深度超过 4,我会尽量避免嵌套 ifelse。 Ray Waldin 的方法和我的方法非常相似。
      【解决方案3】:

      可以这样做,为每种类型创建单独的逻辑向量:

      As <- df$type == 'A'
      Bs <- df$type == 'B'
      Cs <- df$type == 'C'
      df$size2[As] <- 3*df$size[As]
      df$size2[Bs] <- df$size[Bs]
      df$size2[Cs] <- 2*df$size[Cs]
      

      但更直接的方法是创建一个单独的查找表,如下所示:

      df$size2 <- c(A=3,B=1,C=2)[as.character(df$type)] * df$size
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-04
        • 1970-01-01
        • 2014-12-13
        • 1970-01-01
        • 1970-01-01
        • 2016-09-24
        相关资源
        最近更新 更多