我经常发现自己使用
for
循环来执行涉及多个数据帧的按行操作,如下例所示:
# Sample data
set.seed(123)
df1 <- data.frame(a = sample(1:100, size = 20), b = sample(letters, size = 20))
df2 <- data.frame(c = sample(1:100, size = 20), d = sample(letters, size = 20))
# Sample loop operation
for (i in 1:nrow(df2)){
number.2 <- df2$c[i]
letter.1 <- df1$b[df1$a == number.2]
df2$x[i] <- ifelse(!is_empty(letter.1), paste0(letter.1), paste0("No match"))
}
代码做了我想要的,我只是怀疑有一种更优雅的方法来实现它。
特别是:
for (i in 1:nrow)
语法感觉很笨拙,并且
子集化和
ifelse
语句的组合似乎比必要的步骤更多(并且读起来有点混乱)。
如果有任何关于更有效方法的建议,我们将不胜感激。特别是,我们如何使用
apply
系列函数来做到这一点?谢谢!
使用
left_join
:注意 - 比较您的 x
列和 b
列
left_join(df2, df1, join_by(c == a)) %>%
mutate(b = replace_na(b, 'No match'))
c d x b
1 89 v No match No match
2 34 z No match No match
3 93 g No match No match
4 69 p p p
5 72 q x x
6 76 r No match No match
7 63 y No match No match
8 13 b No match No match
9 82 d No match No match
10 91 m No match No match
11 25 e w w
12 38 f No match No match
13 21 c No match No match
14 79 i q q
15 41 u No match No match
16 47 o No match No match
17 60 t No match No match
18 16 j No match No match
19 6 x No match No match
20 96 n No match No match
您在这里所得到的是编写通用操作的很长的方法。这是使用
match()
的单行代码,或者您可以使用 merge
或 dplyr
的 join
函数之一使其更通用,适用于更多种类的案例和列。
df2$result = df1[match(df2$c, df1$a), "b"]
df2
# c d x result
# 1 89 v No match <NA>
# 2 34 z No match <NA>
# 3 93 g No match <NA>
# 4 69 p p p
# 5 72 q x x
# 6 76 r No match <NA>
# 7 63 y No match <NA>
# 8 13 b No match <NA>
# 9 82 d No match <NA>
# 10 91 m No match <NA>
# 11 25 e w w
# 12 38 f No match <NA>
# 13 21 c No match <NA>
# 14 79 i q q
# 15 41 u No match <NA>
# 16 47 o No match <NA>
# 17 60 t No match <NA>
# 18 16 j No match <NA>
# 19 6 x No match <NA>
# 20 96 n No match <NA>