创建具有不同列的元素数的列

时间:2015-03-16 19:03:09

标签: r

我有一个DF

 x y z
 1 1 1
 1 2 5
 2 2 5
 3 3 5

我想在R中有一个简单的命令来生成一个新的DF列,它是我原始DF的计数,如下所示:

 x y z xcount ycount zcount
 1 1 1 2      1      1
 1 2 5 2      2      3
 2 2 5 1      2      3
 3 3 5 1      1      3

我知道这是一个简单的问题,甚至我想到它的方式也因我之前与Stata的经历而受到妨碍。我已经研究过使用table函数,但是返回的向量的长度等于唯一值的数量。我可以将这些值映射到R中的新列,但这看起来很笨拙。

3 个答案:

答案 0 :(得分:2)

这是一个很长的单行:

cbind(df, setNames(lapply(df, function(x) ave(x, x, FUN = length)),
  paste0(names(df), "count")))
#  x y z xcount ycount zcount
#1 1 1 1      2      1      1
#2 1 2 5      2      2      3
#3 2 2 5      1      2      3
#4 3 3 5      1      1      3

重要的部分是:

> lapply(df, function(x) ave(x, x, FUN = length))
$x
[1] 2 2 1 1

$y
[1] 1 2 2 1

$z
[1] 1 3 3 3

其余的是化妆品。


您可以将其放入一个易于处理的功能中:

dfcount <- function(df) cbind(df, setNames(lapply(df, function(x) ave(x, x, FUN = length)), paste0(names(df), "count")))
dfcount(df)
#  x y z xcount ycount zcount
#1 1 1 1      2      1      1
#2 1 2 5      2      2      3
#3 2 2 5      1      2      3
#4 3 3 5      1      1      3

答案 1 :(得分:2)

使用data.table

的选项
library(data.table)
nm1 <- names(DF)
nm2 <- paste0(nm1, "count")
setDT(DF)
for(j in seq_along(nm1)) {
  DF[ , c(nm2[j]) := .N, by = c(nm1[j])]
}
DF
#   x y z xcount ycount zcount
#1: 1 1 1      2      1      1
#2: 1 2 5      2      2      3
#3: 2 2 5      1      2      3
#4: 3 3 5      1      1      3

答案 2 :(得分:1)

修改

基于OP已经接受的作为anwser,我得出结论他正在寻找简单的频率,而不是“连续频率”(偶然发生在例如给出的数据中给出相同的结果)。所以我改变了我对以下内容的回答,这与给出的其他答案一致,只是采用了稍微不同的方法:

# With dataframe "a"
a <- read.table(text="x y z
1 1 1
1 2 5
2 2 5
3 3 5
",header=TRUE)

# cbind together the results of merging each vector with its 
# frequencies obtained from table()
a <- do.call(what = cbind, args = lapply(a, function(x) { 
    merge(x = x, y = table(x))
}))

# Remove trailing .x's from variable names
names(a) <- sub(".x", "", names(a), fixed=TRUE)

# Reorder if necessary
a <- a[,c(1,3,5,2,4,6)]

a
#   x y z x.Freq y.Freq z.Freq
# 1 1 1 1      2      1      1
# 2 1 2 5      2      2      3
# 3 2 2 5      1      2      3
# 4 3 3 5      1      1      3

以前的anwser (假设OP想要连续的频率)

a <- read.table(text="x y z
1 1 1
1 2 5
2 2 5
3 3 5
",header=TRUE)

a$countx <- rep(rle(a$x)$lengths, times=rle(a$x)$lengths)
a$county <- rep(rle(a$y)$lengths, times=rle(a$y)$lengths)
a$countz <- rep(rle(a$z)$lengths, times=rle(a$z)$lengths)

结果

#   x y z countx county countz
# 1 1 1 1      2      1      1
# 2 1 2 5      2      2      3
# 3 2 2 5      1      2      3
# 4 3 3 5      1      1      3