根据R中的条件(`if`)语句replace数据框中的值

在下面编码的Rdataframe中,我想用b来代替B出现的所有时间。

 junk <- data.frame(x <- rep(LETTERS[1:4], 3), y <- letters[1:12]) colnames(junk) <- c("nm", "val") 

这提供了:

  nm val 1 A a 2 B b 3 C c 4 D d 5 A e 6 B f 7 C g 8 D h 9 A i 10 B j 11 C k 12 D l 

我最初的尝试是使用forif语句,如下所示:

 for(i in junk$nm) if(i %in% "B") junk$nm <- "b" 

但正如我相信你可以看到,这将取代junk$nm所有值与b 。 我可以看到为什么这样做,但我似乎无法得到它只取代那些原始值为B的垃圾$ nm的情况。

谢谢。

注意:我设法用gsub解决了这个问题,但为了学习的兴趣,RI仍然想知道如何让我原来的方法工作(如果可能的话)

更容易将nm转换为字符,然后进行更改:

 junk$nm <- as.character(junk$nm) junk$nm[junk$nm == "B"] <- "b" 

编辑:如果你确实需要维护nm作为因素,最后加上:

 junk$nm <- as.factor(junk$nm) 

另一个有用的方法来取代价值

  library(plyr) revalue(junk$nm, c("B"="b")) 

简短的回答是:

 junk$nm[junk$nm %in% "B"] <- "b" 

看R介绍中的索引向量 (如果你还没有阅读)。


编辑。 正如在注释中注意到的,这个解决scheme适用于字符向量,因此数据失败。

因素最好的方法是改变等级:

 levels(junk$nm)[levels(junk$nm)=="B"] <- "b" 

由于您显示的数据是因素,因此会使事情稍微复杂一些。 @ diliop的答案通过将nm转换为字符variables来解决问题。 要回到原来的因素,需要进一步的步骤。

另一种方法是操纵因素的水平。

 > lev <- with(junk, levels(nm)) > lev[lev == "B"] <- "b" > junk2 <- within(junk, levels(nm) <- lev) > junk2 nm val 1 A a 2 bb 3 C c 4 D d 5 A e 6 bf 7 C g 8 D h 9 A i 10 bj 11 C k 12 D l 

这很简单,我常常忘记了levels()的replace函数。

编辑:正如@Seth在评论中指出的那样,这可以在一行中完成,而不会损失清晰度:

 within(junk, levels(nm)[levels(nm) == "B"] <- "b") 

在一个命令中最简单的方法是使用which命令,也不需要通过这样做将因素改变为字符:

 junk$nm[which(junk$nm=="B")]<-"b" 

您已经创build了一个以nm为单位的因子variables,所以您要么避免这样做,要么为因子属性添加一个额外的级别。 你也应该避免在data.frame()的参数中使用<-

选项1:

 junk <- data.frame(x = rep(LETTERS[1:4], 3), y =letters[1:12], stringsAsFactors=FALSE) junk$nm[junk$nm == "B"] <- "b" 

选项2:

 levels(junk$nm) <- c(levels(junk$nm), "b") junk$nm[junk$nm == "B"] <- "b" junk