使用如下所示的数据集:
UserID PartnerID Happiness Result
1 2 30 1
2 1 20 1
正如您所看到的,这是重复的。我想把上面这两行合并成一行。我一直在搜索,但没有找到一个可以在这里工作的解决方案。我的理想输出是:
UserID PartnerID Happiness1 Happiness2 Result
1 2 30 20 1
答案 0 :(得分:2)
如果您不厌恶使用软件包,我建议您使用tidyverse
。以下代码应该得到您想要的输出:
#install.packages("devtools")
#devtools::install_github("hadley/tidyverse")
library(tidyverse)
# Create a data.frame
dff <- structure(list(UserID = c(1, 2, 3, 4, 5, 6),
PartnerID = c(2,1, 4, 3, 6, 5),
Happiness = c(30, 20, 40, 50, 30, 20),
Result = c(1, 1, 1, 1, 1, 1)),
.Names = c("UserID", "PartnerID", "Happiness","Result"),
row.names = c(NA, 6L),
class = "data.frame")
# UserID PartnerID Happiness Result
# 1 2 30 1
# 2 1 20 1
# 3 4 40 1
# 4 3 50 1
# 5 6 30 1
# 6 5 20 1
# Reshape the data.frame
dff %>% mutate(grouper = paste(UserID,
PartnerID,
sep = "")) %>%
mutate(grouper = unlist(map(strsplit(grouper,""),
function(x) paste0(sort(x),
collapse="")))) %>%
group_by(grouper) %>%
mutate(Happiness = toString(Happiness)) %>%
ungroup() %>%
dplyr::filter(!duplicated(grouper)) %>%
separate(Happiness, into = c("Happiness1","Happiness2")) %>%
select(-grouper)
此解决方案在%>%
运算符的帮助下使用链式操作。
这里的想法是首先连接UserID和PartnerID列,然后grouper
每行中的字符,创建一个分组列(称为sorting
)。此时,grouper
列应按排序顺序包含用户的ID和其合作伙伴的ID。这意味着用户及其合作伙伴都拥有grouper
列中的值。因此,您可以继续使用group_by
中的tidyverse
功能按grouper
列对数据进行分组。一旦您能够对数据进行分组,您就可以mutate
Happiness
列到一个字符串(这是toString
函数正在执行的操作)。然后,此时您可以ungroup
并过滤掉重复项。取出重复项后,您可以separate
将Happiness
列分为两个不同的列:Happiness1
和Happiness2
。最后,您可以使用grouper
删除select(-grouper)
列。
那应该产生:
# UserID PartnerID Happiness1 Happiness2 Result
# 1 2 30 20 1
# 3 4 40 50 1
# 5 6 30 20 1
我希望这会有所帮助。
答案 1 :(得分:1)
也许是这样的,假设你的数据是(为了清楚起见,我只是添加了更多的玩具数据):
> df
# UserID PartnerID Happiness Result
# 1 4 30 1
# 2 3 20 0
# 3 2 10 0
# 4 1 15 1
#10 13 20 1
# 13 10 25 1
# 5 6 10 0
# 11 12 10 1
# 6 5 10 0
# 12 11 15 1
然后这个:
dups <- duplicated(t(apply(df[,c(1,2)],1,sort)))
cbind(df[, c(1,3)], df[match(df$UserID,df$PartnerID), c(1,3,4)])[dups,]
将为您提供所需的输出:
# UserID Happiness UserID Happiness Result
# 3 10 2 20 0
# 4 15 1 30 1
# 13 25 10 20 1
# 6 10 5 10 0
# 12 15 11 10 1