替换多个列中的值R.

时间:2017-06-30 22:03:28

标签: r database replace

我正在努力替换R中的一些值,我想听听你关于如何继续的建议。在简历中,我有一个带索引的数据,我需要将此索引的值替换为另一个索引。考虑到我在两个索引上都有5564个案例,我想知道如何在整个数据中创建它。

假设这是我的data.frame 1:

a<-sample(1:10, 10);b<- sample(1:10,10); c<- sample(1:10,10) 
d<-sample(1:10, 10)
df1<- cbind(a, b, c, d)
       a  b  c  d
 [1,]  3  4  7  5
 [2,]  2  2  1  7
 [3,]  9  8 10  8
 [4,]  1  1  3  2
 [5,]  7  5  2  9
 [6,] 10  7  4  3
 [7,]  8  3  8  6
 [8,]  6  6  5  1
 [9,]  5 10  9 10
 [10,]  4  9  6  4

现在,我的第二个数据是第二个索引

 index1<- c(1:10) ; index2 <- sample(1:1000, 10)
 df2<- cbind(index1, index2)
            index1 index2
    [1,]      1    877
    [2,]      2    241
    [3,]      3    924
    [4,]      4    197
    [5,]      5    405
    [6,]      6    854
    [7,]      7    852
    [8,]      8    772
    [9,]      9    421
    [10,]     10    646

在恢复中,我需要将df1的索引1的值替换为df2中index2的等效值。我真的没有想法如何解决这个问题,所以任何帮助都会非常受欢迎。

谢谢!

4 个答案:

答案 0 :(得分:1)

我会使用匹配功能。长话短说:

df1[which(df1 %in% df2[,"index1"])] <- df2[,"index2"][match(df1, df2[,"index1"])]

我将解释:

df1 <- cbind(a = sample(1:10, 10), b = sample(1:10, 10), 
            c = sample(1:10, 10), d = sample(1:10, 10))
df2 <- cbind(index1 = 1:10, index2 = sample(1:1000, 10))

df.original <- df1 # to see

df1
#       a  b  c  d
# [1,]  1  1  8  6
# [2,]  2  6  1  9
# [3,]  3  2  2  4
# [4,]  7  9  9  8
# [5,]  8  7 10  5
# [6,] 10 10  3  2
# [7,]  6  5  6 10
# [8,]  9  4  4  3
# [9,]  5  3  7  7
#[10,]  4  8  5  1

找到要切换的位置(向量中的位置)

pos <- which(df1 %in% df2[,"index1"]) 
df1[pos] == df1 # it's the same thing
#         a    b    c    d
# [1,] TRUE TRUE TRUE TRUE
# [2,] TRUE TRUE TRUE TRUE
# [3,] TRUE TRUE TRUE TRUE
# [4,] TRUE TRUE TRUE TRUE
# [5,] TRUE TRUE TRUE TRUE
# [6,] TRUE TRUE TRUE TRUE
# [7,] TRUE TRUE TRUE TRUE
# [8,] TRUE TRUE TRUE TRUE
# [9,] TRUE TRUE TRUE TRUE
#[10,] TRUE TRUE TRUE TRUE

这里每个值都会被交换,但情况可能不一定如此。这就是为什么使用%in%如上所述找到位置值很重要的原因。

查找df2 index1中的哪一个

tomatch <- match(df1, df2[,"index1"]) # all of them.
tomatch
# [1]  1  2  3  7  8 10  6  9  5  4  1  6  2  9  7 10  5  4  3  8  8  1  2  9 10
#[26]  3  6  4  7  5  6  9  4  8  5  2 10  3  7  1
df2[,"index2"][tomatch] # what we want to replace them with
# [1] 829 568 836 717 693  92 645 222 767 107 829 645 568 222 717  92 767 107
#[19] 836 693 693 829 568 222  92 836 645 107 717 767 645 222 107 693 767 568
#[37]  92 836 717 829
df1[pos] <- df2[,"index2"][tomatch]
df1
#        a   b   c   d
# [1,] 829 829 693 645
# [2,] 568 645 829 222
# [3,] 836 568 568 107
# [4,] 717 222 222 693
# [5,] 693 717  92 767
# [6,]  92  92 836 568
# [7,] 645 767 645  92
# [8,] 222 107 107 836
# [9,] 767 836 717 717
#[10,] 107 693 767 829

此外,使用data.frames可以更清晰一些 df1[which(df1 %in% df2$index1)] <- df2$index2[match(df1, df2$index1)]

答案 1 :(得分:0)

不确定你想要这个:

for ( i in seq_len(nrow(df2))){

    df1[df1 == df2[,"index1"][i]] <- df2[,"index2"][i]

}
df1

如果解决方案没问题,我们可以找到更快的方法。

答案 2 :(得分:0)

使用https://example.com/hook?bot=MyBotdplyr的解决方案。 tidyr是最终输出。

df1_new

答案 3 :(得分:0)

这个问题可以通过结合两种方法来解决:

  1. 通过加入&#34;映射&#34;将index1值转换为index2值表格df2df1
  2. 重塑df1以避免单独处理每个列。 dcast()
  3. 对于后者,melt()用于从长格式转换为长格式,dcast()用于从长格式转换为宽格式。

    library(data.table)
    # coercing to data.table
    DT1 <- data.table(df1)
    DT2 <- data.table(df2)
    # reshape from wide to long format,
    # join with mapping table,
    # finally, reshape from long to wide format, remove row count
    dcast(DT2[melt(DT1[, rn := .I], id.vars = "rn"), on = .(index1 = value)],
          rn ~ variable, value.var = "index2")[, rn := NULL][]
    
          a   b   c   d
     1: 924 197 852 405
     2: 241 241 877 852
     3: 421 772 646 772
     4: 877 877 924 241
     5: 852 405 241 421
     6: 646 852 197 924
     7: 772 924 772 854
     8: 854 854 405 877
     9: 405 646 421 646
    10: 197 421 854 197