R:dplyr - 使用“mutate”更改列名称的因子“SI”

时间:2015-02-18 19:40:21

标签: r dplyr

我是这个data.frame。我需要遍历每一列并搜索" SI",然后将其更改为列名称。

我有这个:

SKU             Tv.y.Video  Cómputo     Tecnología
2003091090002P     NO          NO           NO
2003091090002      NO          NO           NO
2003120060006P     NO          NO           NO
2003120060006P     NO          NO           NO
2003120060006      NO          NO           NO
2004121460000P     NO          SI           NO
2004121460000      NO          SI           NO
2004121440002P     NO          SI           NO
2004121440002      NO          SI           NO
2004123030003P     NO          SI           NO

需要得到这个:

         SKU         Tv.y.Video   Cómputo       Tecnología
   2003091090002P      NO          NO           NO
   2003091090002       NO          NO           NO
   2003120060006P      NO          NO           NO
   2003120060006P      NO          NO           NO
   2003120060006       NO          NO           NO
   2004121460000P      NO          Cómputo      NO
   2004121460000       NO          Cómputo      NO
   2004121440002P      NO          Cómputo      NO
   2004121440002       NO          Cómputo      NO
   2004123030003P      NO          Cómputo      NO

我的代码:

我已尝试使用此代码:

df$Tv.y.Video <- mutate(df$Tv.y.Video,
                Tv.y.Video = ifelse(sub("SI", Tv.y.Video), "Tv.y.Video", Tv.y.Video))

但得到了这个消息:

Error in UseMethod("mutate_") : 
  no applicable method for 'mutate_' applied to an object of class "factor"

所以我将该列的类改为字符:

df$Tv.y.Video <- as.character(df$Tv.y.Video)

得到了这个消息:

Error in UseMethod("mutate_") : 
  no applicable method for 'mutate_' applied to an object of class "character"

这是str(df)的结果:

    'data.frame':   10 obs. of  4 variables:
 $ SKU       : Factor w/ 9028 levels "2003014460004",..: 9 8 16 16 15 842 841 840 839 846
 $ Tv.y.Video: chr  "NO" "NO" "NO" "NO" ...
 $ Cómputo   : Factor w/ 2 levels "NO","SI": 1 1 1 1 1 2 2 2 2 2
 $ Tecnología: Factor w/ 2 levels "NO","SI": 1 1 1 1 1 1 1 1 1 1

2 个答案:

答案 0 :(得分:4)

如果你想尝试一下,这里是一个基础R方法:

# change the class to character for all columns:
df[] <- lapply(df, as.character)
# replace SI entries with column names:
df[] <- Map(function(cols, df_names) replace(cols, which(cols == "SI"), 
               df_names), df, names(df) )
df
#              SKU Tv.y.Video C.mputo Tecnolog.a
#1  2003091090002P         NO      NO         NO
#2   2003091090002         NO      NO         NO
#3  2003120060006P         NO      NO         NO
#4  2003120060006P         NO      NO         NO
#5   2003120060006         NO      NO         NO
#6  2004121460000P         NO C.mputo         NO
#7   2004121460000         NO C.mputo         NO
#8  2004121440002P         NO C.mputo         NO
#9   2004121440002         NO C.mputo         NO
#10 2004123030003P         NO C.mputo         NO

评论后编辑:

OP中尝试代码的主要问题:

df$Tv.y.Video <- mutate(df$Tv.y.Video,
                Tv.y.Video = ifelse(sub("SI", Tv.y.Video), "Tv.y.Video", Tv.y.Video))

是您尝试仅在列上直接使用mutate。通常,dplyr使用类似data.frame的对象,而dplyr中的大多数函数都希望将类似data.frame的对象作为第一个参数。在这里,它将是df,因此您需要启动以下内容:

df <- mutate(df, 
      Tv.y.Video = ifelse(Tv.y.Video == "SI", "Tv.y.Video", Tv.y.Video)
)

或者您可以使用&#34; pipe&#34;运算符(%>%),它允许您首先指定data.frame,然后&#34; pipe&#34;它进入mutate。但请注意,引擎盖mutate仍然使用df作为上面显示的第一个参数。 pipe主要使它更容易阅读,并允许您创建由管道连接的长序列操作。管道运营商将是:

df <- df %>% 
        mutate(
          Tv.y.Video = ifelse(Tv.y.Video == "SI", "Tv.y.Video", Tv.y.Video)
)

另请注意,replace会比ifelse更快,这就是我使用它的基本R方法的原因。

答案 1 :(得分:0)

它应该以这种方式工作:

library(dplyr)
df <- mutate(df,Tv.y.Video = ifelse(Tv.y.Video=="SI",
    "Tv.y.Video",Tv.y.Video), Cómputo = ifelse(Cómputo=="SI", "Cómputo",Cómputo),
    Cómputo = ifelse(Tecnología=="SI", "Tecnología",Tecnología))

对于所有三列,它检查是否存在'SI'。如果是,则将“SI”替换为列名。如果没有值没有改变。