我有这样的数据:
用户拥有user_id和一系列其他功能,例如城市和国家/地区, 并且还与多个广告商相关联。在此格式中,每个与该用户关联的广告商都有一行的副本,并且该用户的其余功能将被复制到具有该user_id的每一行中。我想要删除user_ids,并将所有advertiser_ids组合成一个集合,但所有其他功能保持不变。例如,
我希望合并第2行和第3行,并将advertiser_id列变为与该用户关联的一组ID,但所有其他功能保持不变。
答案 0 :(得分:2)
这是一个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
答案 1 :(得分:1)
duplicated()函数返回一个逻辑向量,对于重复行,该向量等于TRUE。让我们调用数据集,您将使用以下行删除所有重复的值:
df <- subset(df, duplicated(df) = TRUE)
如果您想了解更多相关信息,请参阅R Programming wikibook。
答案 2 :(得分:1)
根据您的描述,听起来您只是在寻找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"
根据@ eddi的答案,data.table
也可以轻松完成这两项工作。
答案 3 :(得分:0)
如果您假设所有其他列中的用户数据相同,请尝试:
假设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])