我有一个包含多行的数据集,这是一个联系人详细信息的数据库。有些条目重复多次,但包含不同的信息。例如:
> example
Title Name Email Phone
[1,] "Chair" "Oswald Gruber" "abc@abc.com" "+33 12345"
[2,] "Respondent" "Oswald Gruber" NA "+44 54321"
[3,] "Comm.mngr" "Kaspar Villiger" "qwe@rty.com" "+1 123456"
[4,] "Investment mngr" "Markus Urben" "jkl@jkl.com" NA
[5,] "Responsible" "Markus Urben" "jkl@jkl.com" "+1 33333"
所以我想要的是让每个人只提到一次,但不会丢失信息。因此,如果我在此示例中合并了两个第一行,我想保留电子邮件地址和两个电话号码,但只保留一种标题。
如果有人建议任何解决方案,我将不胜感激。
答案 0 :(得分:2)
一个data.table解决方案:
library(data.table)
mrg <- function(x) paste(unique(x[!is.na(x)]),collapse=", ")
setDT(example)[,list(Title=head(Title,1), Email=mrg(Email), Phone=mrg(Phone)), by="Name"]
# Name Title Email Phone
# 1: Oswald Gruber Chair abc@abc.com +33 12345, +44 54321
# 2: Kaspar Villiger Comm.mngr qwe@rty.com +1 123456
# 3: Markus Urben Investment mngr jkl@jkl.com +1 33333
这将返回自然顺序中的第一个标题,这可能是也可能不是您想要的。它还可以正确整合电子邮件并删除NAs。
答案 1 :(得分:1)
假设您的“示例”对象是data.frame(也可以使用矩阵)。 对于那些您希望保留所有信息的列,您可以这样做(未经测试用于编码拼写错误):
result <- aggregate(example[,c("Phone","Email")], by = list(Name = example[,"Name"]), FUN = paste, sep = ", ")
因此,电话号码和电子邮件地址将作为字符串元素粘贴到单个列中,值由逗号分隔。 或者,
result <- aggregate(example[,c("Phone","Email")], by = list(Name = example[,"Name"]), FUN = c)
将提供2列,其中包含length =特定Name的条目数的向量列表。
对于要保留一个值的列,您必须指定所需的值。如果它始终是第一个值,那将是
result2 <- aggregate(example[,"title"], by = list(Name = example[,"Name"]), function(x) x[1])
然后你可以
merged <- merge(results, result2)
答案 2 :(得分:1)
您可以按Name
进行分组,并将每列转换为列表。
library(dplyr)
dat %>% group_by(Name) %>%
summarise_each(funs(list)) -> res
所以,看起来像是
data.frame(res)
# Name Title Email
# 1 Kaspar Villiger Comm.mngr qwe@rty.com
# 2 Markus Urben Investment mngr, Responsible jkl@jkl.com, jkl@jkl.com
# 3 Oswald Gruber Chair, Respondent abc@abc.com, NA
# Phone
# 1 +1 123456
# 2 NA, +1 33333
# 3 +33 12345, +44 54321
我不知道您想要进一步修改,但您可以轻松删除NA值/重复项,并选择只保留一个标题,稍微更改一下代码。例如,要删除NA /重复项,可以使用funs(list(unique(na.omit(.))))
。
答案 3 :(得分:-2)
我将其拆分为关系数据库。这假设名称可以作为识别人的唯一键。
library(dplyr)
test =
data_frame(
Title = c("Chair", "Respondent", "Comm.mngr", "Investment mngr", "Responsible"),
Name = c("Oswald Gruber", "Oswald Gruber", "Kaspar Villiger", "Markus Urben", "Markus Urben"),
Email = c("abc@abc.com", NA, "qwe@rty.com", "jkl@jkl.com", "jkl@jkl.com"),
Phone = c("+33 12345", "+44 54321", "+1 123456", NA, "+1 33333") )
Person__Title =
test %>%
select(Name, Title) %>%
distinct %>%
filter(!is.na(Title))
Person__Phone =
test %>%
select(Name, Phone) %>%
distinct %>%
filter(!is.na(Phone))
Person__Email =
test %>%
select(Name, Email) %>%
distinct %>%
filter(!is.na(Email))
Person =
test %>%
select(Name) %>%
distinct
然后,如果你想将它们合并在一起,你可以做到
make_list = function(vector)
vector %>%
unique %>%
na.omit %>%
paste(collapse = ", ")
merge =
Person %>%
left_join(Person__Email) %>%
left_join(Person__Phone) %>%
left_join(Person__Title) %>%
group_by(Name) %>%
summarise_each(funs(make_list))
但我不推荐它。在同一个单元中拥有多条信息违背了良好数据设计的原则。