根据其他列的值将列添加到数据框

时间:2014-09-26 19:42:55

标签: r dplyr

我的数据框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}}列,其中IDID行中的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备份?

4 个答案:

答案 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 Name1Name2之间是否只有一个(且只有一个)匹配?

如果是这样,您可以使用 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"))