我的数据框DF
如下所示:
ID Name1 Name2 Group
1234 A1 x
1234 A4 w
1234 A3 q
1234 A A
1234 A2 z
5678 B3 s
5678 B B
...
我需要为每个Group
添加Name1
的{{1}}列,其中ID
与ID
行中的Name1 == Name2
匹配。
因此,逻辑是检查Name1 == Name2,记住该行的ID和Name1值,然后对于具有该ID的每一行,将Name1值放在Group列的每一行中。
结果如下:
ID Name1 Name2 Group
1234 A1 x A
1234 A4 w A
1234 A3 q A
1234 A A A
1234 A2 z A
5678 B3 s B
5678 B B B
...
我不知道如何在数据框中以及从具有不同ID的许多行中执行此操作。我不想使用循环。
mutate()
或lapply()
可能吗?
我可以看到如何在Name1 == Name2的行的Group列中添加Name1值,但是如何为所有匹配的ID备份?
答案 0 :(得分:3)
您可以使用data.table
DT[, Group := Name1[Name1 == Name2], by=ID]
完整详情:
library(data.table)
DT <- as.data.table(DF)
DT[, Group := Name1[Name1 == Name2], by=ID]
ID Name1 Name2 Group
1: 1234 A1 x A
2: 1234 A4 w A
3: 1234 A3 q A
4: 1234 A A A
5: 1234 A2 z A
6: 5678 B3 s B
7: 5678 B B B
8: 1589 C x NA
9: 1589 C y NA
## if `Name1`, `Name2` are NOT characters, use
DT[, Name1 := as.character(Name1)]
DT[, Name2 := as.character(Name2)]
答案 1 :(得分:1)
试一试
x <- merge(x, x[x$Name1 == x$Name2, 1:2], by.x = "ID", by.y = "ID")
names(x)[4] <- "Group"
# ID Name1.x Name2 Group
# 1 1234 A1 x A
# 2 1234 A4 w A
# 3 1234 A3 q A
# 4 1234 A A A
# 5 1234 A2 z A
# 6 5678 B3 s B
# 7 5678 B B B
答案 2 :(得分:0)
另一种可能性:
unsplit(lapply(split(df, df$ID), function(x) {
x$Group <- if(any(y <- x$Name1 %in% x$Name2)) x$Name2[y] else NA
x
}), df$ID)
ID Name1 Name2 Group
1 1234 A1 x A
2 1234 A4 w A
3 1234 A3 q A
4 1234 A A A
5 1234 A2 z A
6 5678 B3 s B
7 5678 B B B
9 1589 C x <NA>
10 1589 C y <NA>
数据强>
df <-
structure(list(ID = c("1234", "1234", "1234", "1234", "1234",
"5678", "5678", "1589", "1589"), Name1 = structure(c(2L, 5L,
4L, 1L, 3L, 7L, 6L, 8L, 8L), .Label = c("A", "A1", "A2", "A3",
"A4", "B", "B3", "C"), class = "factor"), Name2 = structure(c(6L,
5L, 3L, 1L, 7L, 4L, 2L, 6L, 8L), .Label = c("A", "B", "q", "s",
"w", "x", "z", "y"), class = "factor")), .Names = c("ID", "Name1",
"Name2"), row.names = c("1", "2", "3", "4", "5", "6", "7", "9",
"10"), class = "data.frame")
答案 3 :(得分:0)
每个ID Name1
和Name2
之间是否只有一个(且只有一个)匹配?
如果是这样,您可以使用 dplyr 中的mutate
(使用df
,如@Richard Scriven的答案):
require(dplyr)
df[1:7,] %>%
group_by(ID) %>%
mutate(Group = Name1[Name1 %in% Name2])
如果每个ID可以有一个匹配或没有匹配,您可以添加ifelse
语句来处理无匹配情况。
df %>%
group_by(ID) %>%
mutate(Group = ifelse(any(Name1 %in% Name2),
as.character(Name1)[Name1 %in% Name2], "NA"))