根据条件(`if`)语句替换数据框中的值

DQd*_*dlM 114 r recode

在R数据帧编码的下面,我想更换所有时代B 与出现b.

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

这提供:

   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
Run Code Online (Sandbox Code Playgroud)

我最初的尝试是使用forif语句,像这样:

for(i in junk$nm) if(i %in% "B") junk$nm <- "b"
Run Code Online (Sandbox Code Playgroud)

但我相信你可以看到,这个替换所有的值junk$nmb.我可以看到为什么这样做但我似乎无法让它只替换原始值为的那些垃圾$ nm的情况B.

注意:我设法解决了问题gsub但是为了学习RI仍然想知道如何使我的原始方法工作(如果可能的话)

dil*_*iop 201

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

junk$nm <- as.character(junk$nm)
junk$nm[junk$nm == "B"] <- "b"
Run Code Online (Sandbox Code Playgroud)

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

junk$nm <- as.factor(junk$nm)
Run Code Online (Sandbox Code Playgroud)

  • as.character()在处理因素时使生活变得更加容易.+1 (4认同)
  • 如果你有多列怎么办? (2认同)

Ori*_*rat 39

替换值的另一种有用方法

library(plyr)
junk$nm <- revalue(junk$nm, c("B"="b"))
Run Code Online (Sandbox Code Playgroud)


Mar*_*rek 24

简短的回答是:

junk$nm[junk$nm %in% "B"] <- "b"
Run Code Online (Sandbox Code Playgroud)

看看R简介中的索引向量(如果你还没读过).


编辑.正如评论中所注意到的,此解决方案适用于字符向量,因此对数据失败.

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

levels(junk$nm)[levels(junk$nm)=="B"] <- "b"
Run Code Online (Sandbox Code Playgroud)

  • @Thilo`%in%`和`==`之间的一个重要区别是`NA`处理:`c(1,2,NA)== 1`给出`TRUE,FALSE,NA`但是`c(1 ,2,NA)%1%中的%给出"TRUE,FALSE,FALSE".是的,我忘了检查这是否有效:/ (4认同)

Rei*_*son 19

由于您显示的数据是因素,因此它会使事情变得复杂.@diliop的答案通过转换为nm字符变量来解决问题.要回到原始因素,需要进一步的步骤.

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

> lev <- with(junk, levels(nm))
> lev[lev == "B"] <- "b"
> junk2 <- within(junk, levels(nm) <- lev)
> junk2
   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
Run Code Online (Sandbox Code Playgroud)

这很简单,我经常忘记有替换功能levels().

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

within(junk, levels(nm)[levels(nm) == "B"] <- "b")
Run Code Online (Sandbox Code Playgroud)

  • 尼斯.我不知道`levels()`的替换函数.怎么样的内衬`垃圾< - 内(垃圾,水平(nm)[水平(nm)=="B"] < - "b")`? (6认同)
  • @Marek**拍打头**只是表明一个人不应该回应关于SO的评论.让我再试一次...... (2认同)

use*_*713 11

在一个命令中执行此操作的最简单方法是使用which命令,也不需要通过执行以下操作将因子更改为字符:

junk$nm[which(junk$nm=="B")]<-"b"
Run Code Online (Sandbox Code Playgroud)


42-*_*42- 5

您已经创建了一个因子变量,nm因此您需要避免这样做,或者为因子属性添加额外的级别.您还应该避免<-在data.frame()的参数中使用

选项1:

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

选项2:

levels(junk$nm) <- c(levels(junk$nm), "b")
junk$nm[junk$nm == "B"] <- "b"
junk
Run Code Online (Sandbox Code Playgroud)