添加新列以计算重复的组值

时间:2014-09-03 09:00:31

标签: r count

我有这两列的DF:P_ID和PR_ID。每个行都有重复的行,有些P_ID有多个PR_ID,反之亦然。 可重复的例子:

DF <- data.frame(
    'p_id' = sample(100:300, 100, replace=T),
    'pr_id' = sample(100:300, 100, replace=T)
)

我想根据每个p_id有多少pr_id来添加一个新的列pr_count到DF。

在实践中,一些p_ids没有任何pr_id。我希望他们的pr_count为0。

所需的输出格式:

p_id  pr_id     pr_count
----  ----      --------
1     2             0

2 个答案:

答案 0 :(得分:1)

数字ID值

为此,ave()是您正在寻找的主力。使用一些没有pr_id的p_id获取数据框,反之亦然:

DF <- data.frame(
  'p_id' = sample(100:300, 100, replace=T),
  'pr_id' = sample(100:300, 100, replace=T)
)

DF$pr_id[sample(1:100,10)] <- NA
DF$p_id[sample(1:100,10)] <- NA

使用ave()创建向量pr_count

DF <- within(DF,{
  pr_count <- ave(pr_id,p_id,
                  FUN = function(x)length(na.omit(x))
                  )
  pr_count[is.na(p_id)] <- 0  
})

请注意,pr_countp_id时,您必须替换NA中的值。默认情况下,ave()只会在pr_idp_id的地方复制NA的值。

一般解决方案

您必须记住,ave()将创建一个与初始x参数类型相同的向量(在本例中为pr_id)。因此,如果您有字符ID,则还需要在结尾处转换为数字:

DF <- data.frame(
  'p_id' = sample(letters, 100, replace=T),
  'pr_id' = sample(LETTERS, 100, replace=T),
  stringsAsFactors = FALSE
)

DF$pr_id[sample(1:100,10)] <- NA
DF$p_id[sample(1:100,10)] <- NA

DF <- within(DF,{
  pr_count <- ave(pr_id,p_id,
                  FUN = function(x)length(na.omit(x))
                  )
  pr_count[is.na(p_id)] <- 0
  pr_count <- as.numeric(pr_count)

})

这再次给出了期望的结果:

> str(DF)
'data.frame':   100 obs. of  3 variables:
 $ p_id    : chr  "m" "f" "u" "n" ...
 $ pr_id   : chr  "Y" "W" "R" "M" ...
 $ pr_count: num  2 2 3 2 2 2 2 5 4 2 ...

警告 ave()的这种行为也意味着您会遇到很多因素问题。在使用此功能之前,请确保您的ID不会作为数据框中的因素存储!!!

答案 1 :(得分:0)

尝试:

'p_id' = sample(100:300, 10, replace=T)
'pr_id' = sample(100:300, 10, replace=T)

DF <- data.frame(p_id, pr_id)
outdf = expand.grid(p_id, pr_id)
outdf$count = ifelse(outdf$Var1==p_id & outdf$Var2==pr_id, 1, 0)
names(outdf)= c("p_id","pr_id","count")

head(outdf)
    p_id pr_id count
1    295   193     1
2    112   193     0
3    283   193     0
4    163   193     0
5    202   193     0
6    135   193     0