按索引替换行

时间:2015-08-13 09:48:36

标签: r data.table

在以下示例中:

library(data.table)
df1 <- data.table("1A"=c(0,0,0,0),"1B"=c(4:3),"2A"=c(0,0,0,0), "2B"=c(4:3))
df2 <- data.table("1A"=c(0,0),"1B"=c(1:2),"2A"=c(0,0), "2B"=c(1:2))

df1
#    1A 1B 2A 2B
# 1:  0  4  0  4
# 2:  0  3  0  3
# 3:  0  4  0  4
# 4:  0  3  0  3

df2
#    1A 1B 2A 2B
# 1:  0  1  0  1
# 2:  0  2  0  2

indx = c(1,3)
indx
# [1] 1 3

df1[indx,] <- df2
df1
#    1A 1B 2A 2B
# 1:  0  1  0  1
# 2:  0  3  0  3
# 3:  0  2  0  2
# 4:  0  3  0  3

我成功用df2替换df1中的第1行和第3行。在我的真实数据中复制相同的练习,我遇到了错误:

  

不能在同一查询中两次分配到同一列(重复   检测的)。

在这个表达式中:

Z4[positionpdis,] <- ZpdisRow2

对象具有以下属性:

is.data.table(ZpdisRow2)
# [1] TRUE
is.data.table(Z4)
# [1] TRUE
dim(Z4)
# [1] 7968 7968
dim(Z4[positionpdis,])
# [1]   48 7968
dim(ZpdisRow2)
# [1]   48 7968
str(positionpdis)
# int [1:48] 91 257 423 589 755 921 1087 1253 1419 1585 ...
> length(unique(positionpdis))
# [1] 48

可能是错误的来源是什么?

1 个答案:

答案 0 :(得分:4)

我猜我们可能在原始数据集中有一些重复的列名。例如,如果我们将第3列名称更改为与第一列名称相同,则会出现错误。

colnames(df1)[3] <- '1A'
df1[indx,] <- df2
  

[<-.data.table中的错误(*tmp*,indx ,, value = list(1A = c(0,   0),:        无法在同一查询中两次分配到同一列(检测到重复项)。

我们可以使用make.unique使列名称唯一,这对于此类案例而言是一个方便的函数,而不必查看重复项的每个列名称。

 colnames(df1) <- make.unique(colnames(df1)) 
 df1[indx,] <- df2
 df1
 #  1A 1B 1A.1 2B
 #1:  0  1    0  1
 #2:  0  3    0  3
 #3:  0  2    0  2
 #4:  0  3    0  3

另一个应该与重复列名一起使用的选项是set。它非常有效,因为避免了[.data.table中的开销。在这里,我们循环遍历列索引(seq_along(df1)),并基于行(i)和列(j)索引,我们set中的值为&# 39; DF1&#39;使用&#39; df2&#39;。

的值
 for(j in seq_along(df1)){
           set(df1, i= as.integer(indx), j=j, df2[[j]])
  }
 df1
#   1A 1B 1A 2B
#1:  0  1  0  1
#2:  0  3  0  3
#3:  0  2  0  2
#4:  0  3  0  3