我正在尝试用另一个data.frame
中满足条件(小于零)的值替换为另一个值:
> df
id val1 val2 val3
1 a 1 0 -1
2 b -1 NA 2
> replacevals
id val1 val2 val3
1 a 1 3 0
2 b 2 NA 3
所需的输出:
id val1 val2 val3
1 a 1 0 0
2 b 2 NA 2
我知道两个数据帧的结构相同。我可以像这样进行所需的替换...
negs <- !is.na( df ) & df < 0 # logical matrix
df[negs] <- replacevals[negs]
...但是现在列类已更改:
> sapply(df, class)
id val1 val2 val3
"character" "character" "numeric" "character"
在这种情况下,可以通过将类从替换数据映射到最终数据来将它们转换回正确的值:
df[] <- Map(`class<-`, df, sapply(replacevals, class))
但是,我正在处理一些大型数据集,因此宁愿避免花时间进行类型强制。 R官方文档建议避免这种情况,但我看不到另一种简单的方法。
不建议使用[进行矩阵索引(带有逻辑或2列整数矩阵i的x [i])。为了提取,首先将x强制转换为矩阵。要进行替换,逻辑矩阵索引必须与x具有相同的维数。一次更换一列,可能会发生多种类型的强制转换。
有更好的方法吗?
数据
df <- data.frame(id = c('a','b'), val1 = c(1,-1), val2 = c(0,NA),
val3 = c(-1,2), stringsAsFactors = F)
replacevals <- data.frame(id = c('a','b'), val1 = c(1,2), val2 = c(3,NA),
val3 = c(0,3), stringsAsFactors = F)
答案 0 :(得分:2)
我们只需要在数字列上创建条件
j1 <- sapply(df, is.numeric)
negs <- !is.na( df[j1] ) & df[j1] < 0 # logical matrix
df[j1][negs] <- replacevals[j1][negs]
df
# id val1 val2 val3
#1 a 1 0 0
#2 b 2 NA 2
str(df)
#'data.frame': 2 obs. of 4 variables:
# $ id : chr "a" "b"
# $ val1: num 1 2
# $ val2: num 0 NA
# $ val3: num 0 2