我有这样的数据:
其中一个用户有一个 user_id 和一堆其他的特征,比如城市和国家,并且还与多个广告商相关联。在这种格式中,与用户关联的每个广告商都有一个行的副本,并且用户的其余功能在具有该 user_id 的每一行中都被复制。我想对 user_ids 进行重复数据删除并将所有 adser_ids 合并为一组,但让所有其他功能保持不变。例如,
我希望将第 2 行和第 3 行组合起来,并使 adser_id 列成为与该用户关联的一组 id,但所有其他功能保持不变。
我有这样的数据:
其中一个用户有一个 user_id 和一堆其他的特征,比如城市和国家,并且还与多个广告商相关联。在这种格式中,与用户关联的每个广告商都有一个行的副本,并且用户的其余功能在具有该 user_id 的每一行中都被复制。我想对 user_ids 进行重复数据删除并将所有 adser_ids 合并为一组,但让所有其他功能保持不变。例如,
我希望将第 2 行和第 3 行组合起来,并使 adser_id 列成为与该用户关联的一组 id,但所有其他功能保持不变。
这是一个data.table
解决方案:
library(data.table)
#example data
dt = data.table(user_id = c(1,2,2,3), advertiser_id = c(1:4), other_data = c(4:1))
# user_id advertiser_id other_data
#1: 1 1 4
#2: 2 2 3
#3: 2 3 2
#4: 3 4 1
dt[, advertiser_list := list(list(advertiser_id)), by = user_id][
# ^^^ first collect advertisers into a list by user_id
!duplicated(user_id)][, # now select the unique users
advertiser_id := NULL] -> dt # finally remove the advertiser_id column
dt
# user_id other_data advertiser_list
#1: 1 4 1
#2: 2 3 2,3
#3: 3 1 4
从您的描述来看,您似乎只是在寻找aggregate
. 考虑以下:
> df = data.frame(user_id = c(1,2,2,3),
+ advertiser_id = c(1:4),
+ other_data = letters[c(1, 2, 2, 3)])
> df
user_id advertiser_id other_data
1 1 1 a
2 2 2 b
3 2 3 b
4 3 4 c
> aggregate(advertiser_id ~ . , df, I)
user_id other_data advertiser_id
1 1 a 1
2 2 b 2, 3
3 3 c 4
上面将“advertiser_id”列转换为list
,可以使用str
. 这可能很方便,但也可能难以使用,例如,如果您想稍后将输出保存到 csv 文件。
> str(aggregate(advertiser_id ~ . , df, I))
'data.frame': 3 obs. of 3 variables:
$ user_id : num 1 2 3
$ other_data : Factor w/ 3 levels "a","b","c": 1 2 3
$ advertiser_id:List of 3
..$ 0:Class 'AsIs' int 1
..$ 4:Class 'AsIs' int [1:2] 2 3
..$ 8:Class 'AsIs' int 4
一种不太灵活的替代方法是将“advertiser_id”列连接为字符串。
> aggregate(advertiser_id ~ . , df, paste, collapse = ", ")
user_id other_data advertiser_id
1 1 a 1
2 2 b 2, 3
3 3 c 4
> str(aggregate(advertiser_id ~ . , df, paste, collapse = ", "))
'data.frame': 3 obs. of 3 variables:
$ user_id : num 1 2 3
$ other_data : Factor w/ 3 levels "a","b","c": 1 2 3
$ advertiser_id: chr "1" "2, 3" "4"
data.table
按照@eddi 的回答,这两者也可以很容易地完成。
duplicated() 函数返回一个逻辑向量,对于重复的行,该向量等于 TRUE。让我们调用 df 您的数据集,您将使用以下行删除所有重复值:
df <- subset(df, duplicated(df) = TRUE)
如果您想了解更多信息,请参阅R Programming wikibook 。
如果您假设所有其他列中的用户数据相同,请尝试:
假设df
是您的原件data.frane
:
#pull add ad_id into one column for each user_id
ad = sapply(unique(df$user_id),function(x){paste(df$advertiser_id[df$user_id==x],collapse=",")}
names(ad) = unique(df$user_id)
#Drop all extra rows
df = df[!duplicated(df[,1]),]
#add a column with combined ad_id
df = cbind(df,ad[df$user_id])