逐字符替换数据

时间:2013-11-04 12:46:44

标签: r

如果我用data[data<0] <- "Down"替换一些字符,然后用data[data>0] <- "Up"替换,我将所有值都改为“Up”,但如果我反转替换,我会按照我的方式工作等。

data<-runif(30, min=-5, max=5)
data[data<0]<-"Down"
data[data>0]<-"Up"
#[1] "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up"
#[16] "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up" "up"

但如果我这样做,我会得到正确的结果:

data<-runif(30, min=-5, max=5)
data[data>0]<-"Up"
data[data<0]<-"Down"
#[1] "down" "up"   "up"   "down" "down" "down" "down" "down" "down" "down"
#[11] "down" "down" "up"   "down" "down" "down" "up"   "up"   "down" "up"  
#[21] "up"   "down" "up"   "up"   "down" "down" "up"   "up"   "down" "down"

解决方案很简单,做第二个,但我很好奇为什么会这样。起初我认为它是转换为字符所涉及的东西但是,它不可能是因为然后改变序列不会影响或它会影响相同的方式。 有什么想法吗?

2 个答案:

答案 0 :(得分:2)

R中的向量只能保存一种类型的值。该向量最初是使用数值创建的。

在你的第一段代码(data[data<0]<-"Down")中,你的赋值将向量模式从数字转换为字符。向量中的其余数字从数字模式更改为字符模式。在该赋值结束时,向量看起来像......

 [1] "Down"              "4.50482521206141"  "Down"             
 [4] "Down"              "Down"              "Down"             
 [7] "3.81024733651429"  "1.01603321265429"  "Down"             
[10] "3.30486473860219"  "4.82019837480038"  "1.3452106853947"  
[13] "2.02783531043679"  "Down"              "Down"             
[16] "Down"              "Down"              "Down"             
[19] "4.59091864991933"  "Down"              "2.09894138388336" 
[22] "Down"              "0.638334625400603" "1.58013242762536" 
[25] "2.14735288871452"  "Down"              "1.67530178790912" 
[28] "4.91423513041809"  "Down"              "1.71986542874947" 

当涉及第二次比较时 - 发生隐式类型转换。 R不会让你比较数字和字符串。所以数字0被转换为字符串“0”。 (即。data[data>0]被强制执行data[data>"0"]

这就是为什么它没有像你想象的那样工作的原因。 (具有值“down”的所有字符串和具有数字作为字符串的字符串都将测试为大于字符串“0”。)

在第二个示例中,数字字符串以“ - ”开头,字符编码中的字符编码小于“0”的字符编码。

答案 1 :(得分:1)

解决方案是避免转换为字符,并同时进行2次测试:

ifelse(data>0,"Up","Down")

修改

为了解释发生了什么,奇怪的是R使用符号“ - ”来检查角色是否为正面。

"-a" < 0
[1] TRUE

所以当你按照这个顺序(&gt;然后&lt;)时,你保持标志并且它有效。

修改 “ - ”在ASCII中以“0”之前排序。这是一个可以接受ascii字符并返回小数值的函数:

asc <- function(x) { strtoi(charToRaw(x),16L) }
> asc("0")
[1] 48
> asc("-")
[1] 45