您可以使用 apply 对数据帧的每一行进行迭代操作吗? [重复]

问题描述 投票:0回答:3

我经常发现自己使用

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"))
}

代码做了我想要的,我只是怀疑有一种更优雅的方法来使用

apply

有没有办法使用

apply
函数系列来做到这一点?

r for-loop apply
3个回答
3
投票

使用

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

3
投票

您在这里所得到的是编写通用操作的很长的方法。这是使用

match()
的单行代码,或者您可以使用
merge
dplyr
join
函数之一使其更通用,适用于更多种类的案例和列。

当您匹配一个值时,

match
效果很好。如果您要匹配多列,则
merge
join
效果很好。如果您有更复杂的条件,例如
>=
而不是
==
,那么您需要“非等值连接”,这在
dplyr
data.table
中得到支持。

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>

2
投票

另一个基本 R 选项,带有

merge

transform(
    merge(df2, df1, by.x = "c", by.y = "a", all.x = TRUE),
    x = ifelse(is.na(b), "No Match", b)
)[-3]

这给出了

    c d        x
1   6 x No Match
2  13 b No Match
3  16 j No Match
4  21 c No Match
5  25 e        w
6  34 z No Match
7  38 f No Match
8  41 u No Match
9  47 o No Match
10 60 t No Match
11 63 y No Match
12 69 p        p
13 72 q        x
14 76 r No Match
15 79 i        q
16 82 d No Match
17 89 v No Match
18 91 m No Match
19 93 g No Match
20 96 n No Match
© www.soinside.com 2019 - 2024. All rights reserved.