删除R中的重复项

时间:2013-06-10 21:28:37

标签: r duplicates

我有这样的数据: Observations

用户拥有user_id和一系列其他功能,例如城市和国家/地区, 并且还与多个广告商相关联。在此格式中,每个与该用户关联的广告商都有一行的副本,并且该用户的其余功能将被复制到具有该user_id的每一行中。我想要删除user_ids,并将所有advertiser_ids组合成一个集合,但所有其他功能保持不变。例如,

我希望合并第2行和第3行,并将advertiser_id列变为与该用户关联的一组ID,但所有其他功能保持不变。

4 个答案:

答案 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])