我有一个数据集,我想在某些条件下替换数据集中的值。
set.seed(100)
Mydata=sample(-5:5,size = 1000,replace = T)
Mydata=as.data.frame(matrix(Mydata,nrow = 100))
Mydata[Mydata<=-1 & Mydata>-1.5] = "A"
Mydata[Mydata<=-1.5 & Mydata>-2] = "B"
Mydata[Mydata<=-2] = "C"
Mydata[Mydata>-1] = "D"
结果应该是填充“A”,“B”,“C”和“D”的数据帧。但是,当我运行代码时,结果只用“D”填充。我想知道问题是什么。感谢。
答案 0 :(得分:3)
问题与您用字符替换数字这一事实有关。向量只能包含一个类的元素,所以当你用&#34; A&#34;替换一些元素时。在第一步中,具有这些元素的所有列都被强制转换为字符向量。看看:
> set.seed(100)
> Mydata=sample(-5:5,size = 50,replace = T)
> Mydata=as.data.frame(matrix(Mydata,nrow = 10))
> str(Mydata)
'data.frame': 10 obs. of 5 variables:
$ V1: int -2 -3 1 -5 0 0 3 -1 1 -4
$ V2: int 1 4 -2 -1 3 2 -3 -2 -2 2
$ V3: int 0 2 0 3 -1 -4 3 4 1 -2
$ V4: int 0 5 -2 5 2 4 -4 1 5 -4
$ V5: int -2 4 3 4 1 0 3 4 -3 -2
> Mydata[Mydata<=-1 & Mydata>-1.5] = "A"
> str(Mydata)
'data.frame': 10 obs. of 5 variables:
$ V1: chr "-2" "-3" "1" "-5" ...
$ V2: chr "1" "4" "-2" "A" ...
$ V3: chr "0" "2" "0" "3" ...
$ V4: int 0 5 -2 5 2 4 -4 1 5 -4
$ V5: int -2 4 3 4 1 0 3 4 -3 -2
有趣的是,事实证明R允许你在(in)相等的测试中使用字符。因此,当您应用后续规则时,它将继续替换满足不等式的字符值,而不是抛出警告或错误。例如:
> char_vec <- c("A", 1, 2, -1)
> char_vec
[1] "A" "1" "2" "-1"
> char_vec > 0
[1] TRUE TRUE TRUE FALSE
事实证明,所有大写字母(以及所有小写字母)都大于-1,因此整个矩阵在最后一步中最终被D替换。
> toupper(letters) > -1
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[19] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
防止此行为的最简单方法是使用ifelse
,正如Aaghaz所指出的那样。另一个选择是创建一个新矩阵而不是逐步覆盖原始矩阵:
> Newdata <- Mydata
> Newdata[Mydata<=-1 & Mydata>-1.5] = "A"
> Newdata[Mydata<=-1.5 & Mydata>-2] = "B"
> Newdata[Mydata<=-2] = "C"
> Newdata[Mydata>-1] = "D"
答案 1 :(得分:2)
您可以使用ifelse
ifelse(Mydata <= -1 & Mydata > -1.5, "A",
ifelse(Mydata <= -1.5 & Mydata > -2, "B",
ifelse(Mydata <= -2, "C", "D")))
或者更严格的矢量化if
(检查true和false是同一类型)并且比base ifelse
更快
if_else(Mydata <= -1 & Mydata > -1.5, "A",
if_else(Mydata <= -1.5 & Mydata > -2, "B",
if_else(Mydata <= -2, "C", "D")))