【问题标题】:merge 2 data frames in a loop for each column in one of them为其中一个中的每一列在循环中合并 2 个数据框
【发布时间】:2018-12-11 03:05:13
【问题描述】:

我有 2 个这样的数据框:

mydf <- data.frame(a=sample(1:10, 20, replace=T), b=sample(1:10, 20, replace=T), c=sample(1:10, 20, replace=T))
mydf
    a  b  c
1  10  2  5
2   9  3 10
3   5  3  6
4   5  7  8
5   9  4  3
6  10 10  2
7   6 10  7
8   9  9  5
9   7  5  8
10 10  3  2
11  9 10  4
12  3  4  7
13  7  6  5
14  5  9  7
15  9  9  9
16  5  5  2
17  9  8  4
18  1  9  9
19  7  8  7
20  2 10  7
codetable <- data.frame(code=1:10, translation=LETTERS[1:10])
codetable
   code translation
1     1           A
2     2           B
3     3           C
4     4           D
5     5           E
6     6           F
7     7           G
8     8           H
9     9           I
10   10           J

我事先不知道第一个数据框可能有多少列...

我在这里要做的是将mydf 中的数字替换为对应的translation 字母,由codetable 引导。

我想过合并mydf 中每一列的两个数据框,但apply 可能有更好的解决方案。

这是我的尝试:

for (n in dim(mydf)[2]){
  mydf <- merge(mydf, codetable, by.x=names(mydf)[n], by.y='code')
 }
 mydf
   c  a  b translation
1  1  8  1           A
2  1  6  9           A
3  2  3  7           B
4  2  3 10           B
5  2  1 10           B
6  3 10  7           C
7  3  7  9           C
8  4  7 10           D
9  5 10  3           E
10 5  9  2           E
11 6  9  4           F
12 7  8  6           G
13 7  6  4           G
14 7  4  6           G
15 8  5  6           H
16 8  9  5           H
17 8  4  9           H
18 8  3  4           H
19 8  3  6           H
20 9  5  6           I

但我遇到的问题是,我最终得到一个而不是 abc 的 3 个 translation 列...

我怎样才能以一种实际可行的有效方式做到这一点?谢谢!

【问题讨论】:

  • 失败是因为你需要for (n in 1:dim(mydf)[2])。您忘记了 1:,所以它只是评估 n = dim(mydf)[2],即 3。
  • 天哪!菜鸟失误

标签: r dataframe merge apply


【解决方案1】:

我们可以在mydfmatch 的所有列上使用lapply mydf 中的值与codetable 中的code 列并得到对应的translation

mydf[] <- lapply(mydf, function(x) codetable$translation[match(x, codetable$code)])

mydf
#   a b c
#1  H F F
#2  H F J
#3  A I I
#4  H G C
#5  A E G
#6  G D H
#7  J G C
#8  H B G
#9  J I F
#10 C I B
#.....

这可以扩展到任意数量的列,而无需更改任何代码。

数据

set.seed(234)
mydf <- data.frame(a=sample(1:10, 20, replace=T), 
                   b=sample(1:10, 20, replace=T), 
                   c=sample(1:10, 20, replace=T))

【讨论】:

  • 这正是我想要的
【解决方案2】:

使用stack + unstackmatch

mydf = stack(mydf)
mydf$values = codetable$translation[match(mydf$values,codetable$code)]
mydf = unstack(mydf)
mydf
   a b c
1  A D G
2  E C H
3  G G D
4  G H I
5  A D J
6  C F E
7  I A J
8  E E H
9  B F F
10 B I G
11 F B G
12 A H H
13 B D C
14 C H G
15 I H D
16 F B G
17 G I D
18 G A I
19 F G A
20 J A D

【讨论】:

    【解决方案3】:

    与 Ronak 的回答类似,但使用 dplyr::mutate_all

    library(dplyr)
    mydf %>% mutate_all(funs(codetable$translation[match(., codetable$code)]))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多