没有类型强制的数据帧矩阵索引

时间:2018-09-05 14:56:40

标签: r

我正在尝试用另一个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)

1 个答案:

答案 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