2014-09-26 233 views
0

我的數據框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 
... 

我需要添加一列GroupName1每個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滾動備份?

回答

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

試試這個

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 
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") 
+0

我得到一個錯誤說「組長度爲零,但數據長度是> 0「 – brno792 2014-09-26 20:48:55

0

會不會有永遠Name1之間的一個(也是唯一一個)匹配和每個ID有Name2

如果是這樣,你可以(使用df在@Richard斯克裏芬的答案)使用mutatedplyr此:

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")) 
+0

例如,當我運行mutate()時出現錯誤:」不兼容的大小(3),期望4(組大小)「。 ID是左側一些其他列的子集。但是,我在我的group_by() – brno792 2014-09-26 21:28:50

+0

中包括那些是的,應該總是隻有一個匹配每個ID – brno792 2014-09-26 21:30:33

+0

@ brno792你可以'輸入'你的數據集(或它的一部分)到你的問題?這聽起來像是我沒有考慮過的其他結構。 – aosmith 2014-09-26 21:36:16