#r #dplyr
#r #dplyr
Вопрос:
Привет всем, у меня есть фрейм данных, такой как ::
Families Species Event Groups
1 A,B,C,D SP1 4,5,6,1 G1,G2,G3,G4
2 A,A,C SP2 4,4,2 G1,G4
3 B SP2 5 G1
4 A SP3 2 G8
5 C SP3 1 G9
и идея заключается в том, что я хотел бы объединить строки, Species
когда :
- по крайней мере , один элемент
Families
Event
иGroups
является общим для другогоSpecies
.
Так, например, мы видим, что для SP2
row2
этого :
- в
Families
A также присутствует вFamilies
ofSP1
(A, B, C, D) - в
Event
4 также присутствует вEvent
SP1
(4,5,6,1) - в группах G1 и G4 также присутствуют в
Groups
офSP1
(G1, G2,G3, G4)
И
для SP2
row3
этого :
- в
Families
B также присутствует вFamilies
ofSP1
(A, B, C, D) - in
Event
5 также присутствует вEvent
ofSP1
(4,5,6,1) - в группах G1 также присутствует в
Groups
офSP1
(G1, G2, G3, G4)
затем я могу объединить rows
and row3
, поскольку они оба имеют общие значения с row1
of SP1
.
итак, вот ожидаемый результат:
Families Species Event Groups
1 A,B,C,D SP1 4,5,6,1 G1,G2,G3,G4
2 A,A,C,B SP2,SP2 4,4,2,5 G1,G4,G1
3 A SP3 2 G8
4 C SP3 1 G9
Если у кого-то есть идея, это было бы потрясающе, большое вам спасибо за вашу помощь и время.
Вот эти данные :
structure(list(Families = structure(c(3L, 2L, 4L, 1L, 5L), .Label = c("A",
"A,A,C", "A,B,C,D", "B", "C"), class = "factor"), Species = structure(c(1L,
2L, 2L, 3L, 3L), .Label = c("SP1", "SP2", "SP3"), class = "factor"),
Event = structure(c(4L, 3L, 5L, 2L, 1L), .Label = c("1",
"2", "4,4,2", "4,5,6,1", "5"), class = "factor"), Groups = structure(c(2L,
3L, 1L, 4L, 5L), .Label = c("G1", "G1,G2,G3,G4", "G1,G4",
"G8", "G9"), class = "factor")), class = "data.frame", row.names = c(NA,
-5L))
Ответ №1:
вот попытка, используя data.table (но если вы посмотрите, это довольно легко сделать без data.table, просто data.table теперь мой родной язык) :
dt <- structure(list(Families = structure(c(3L, 2L, 4L, 1L, 5L), .Label = c("A",
"A,A,C", "A,B,C,D", "B", "C"), class = "factor"), Species = structure(c(1L,
2L, 2L, 3L, 3L), .Label = c("SP1", "SP2", "SP3"), class = "factor"),
Event = structure(c(4L, 3L, 5L, 2L, 1L), .Label = c("1",
"2", "4,4,2", "4,5,6,1", "5"), class = "factor"), Groups = structure(c(2L,
3L, 1L, 4L, 5L), .Label = c("G1", "G1,G2,G3,G4", "G1,G4",
"G8", "G9"), class = "factor")), class = "data.frame", row.names = c(NA,
-5L))
library(data.table)
setDT(dt)
library(stringr)
dt[, Families := as.character(Families)]
dt[, Event := as.character(Event)]
dt[, Groups := as.character(Groups)]
dt[, n := row.names(.SD) ]
dt2 <- merge(dt,
dt,
by = "Species")[n.x >= n.y]
dt2[, testFamilies := length(intersect(unlist(strsplit(Families.x, ",")), unlist(strsplit(Families.y, ",")))) > 0, by = 1:nrow(dt2)]
dt2[, testEvents := length(intersect(unlist(strsplit(Event.x, ",")), unlist(strsplit(Event.y, ",")))) > 0, by = 1:nrow(dt2)]
dt2[, testGroups := length(intersect(unlist(strsplit(Groups.x, ",")), unlist(strsplit(Groups.y, ",")))) > 0, by = 1:nrow(dt2)]
dt2[, Families := paste0(unique(unlist(strsplit(paste(Families.x, Families.y, sep = ","), ","))), collapse = ","), by = 1:nrow(dt2)]
dt2[, Event := paste0(unique(unlist(strsplit(paste(Event.x, Event.y, sep = ","), ","))), collapse = ","), by = 1:nrow(dt2)]
dt2[, Groups := paste0(unique(unlist(strsplit(paste(Groups.x, Groups.y, sep = ","), ","))), collapse = ","), by = 1:nrow(dt2)]
dt2[(testFamilies == TRUE | testGroups == TRUE | testEvents == TRUE)
amp; !n.x %in% dt2[(testFamilies == TRUE | testGroups == TRUE | testEvents == TRUE) amp; n.x != n.y, n.y]
amp; !n.y %in% dt2[(testFamilies == TRUE | testGroups == TRUE | testEvents == TRUE) amp; n.x != n.y, n.x],
.(Species, Families, Event, Groups)]
Комментарии:
1. Здравствуйте, спасибо, но я попробовал ваш код и не получил ожидаемого результата, dt2 не имеет объединенной строки между строками 2 и 3…
2. Я не понимаю .. В ваших семействах примеров для строк 2 и 3 есть «A, A, C» и «B» .. сын, я думаю, они не должны сливаться .. О .. хорошо, я пропустил «хотя бы один из ..» Я отредактирую свой ответ, чтобы он соответствовал вашей цели..
3. В SP2 row2 также
Familly A
находится вSP2 row1
amp; ВSP2 row3
Familly B
SP2 row1
, поэтому я объединяю дваSP2 row2
иrow3
в одну строку. Смотрите в примере, я объяснил это лучше с более подробной информацией. Хорошо, я видел, что вы только что увидели этот момент, спасибо.4. И где-то в моем коде есть небольшая ошибка .. Я смотрю на это ..
5. Спасибо, но опять же, это не похоже на ожидаемый результат… Строка 1 была удалена, и слияние между строками 2 и строкой 3 не происходит, как ожидалось… Вы можете увидеть, каков точный ожидаемый результат в сообщении, если вы хотите сослаться на него