9

次のようなデータフレームがあります。列順に並んでいますtime

入力 -

df = data.frame(time = 1:20,
            grp = sort(rep(1:5,4)),
            var1 = rep(c('A','B'),10)
            )

head(df,10)
   time grp var1
1   1   1    A
2   2   1    B
3   3   1    A
4   4   1    B
5   5   2    A
6   6   2    B
7   7   2    A
8   8   2    B
9   9   3    A
10 10   3    B

これまでのところ、つまり各グループのその時点まで、個別の値var2を計算しない別の変数を作成したいと思います。これは、 を使用した場合に得られるものとは少し異なります。var1timegrpn_distinct

期待される出力 -

   time grp var1 var2
1   1   1    A    1
2   2   1    B    2
3   3   1    A    2
4   4   1    B    2
5   5   2    A    1
6   6   2    B    2
7   7   2    A    2
8   8   2    B    2
9   9   3    A    1
10 10   3    B    2

これについて言う関数を作成し、cum_n_distinctそれを次のように使用したい-

d_out = df %>%
  arrange(time) %>%
  group_by(grp) %>%
  mutate(var2 = cum_n_distinct(var1))
4

4 に答える 4

2

試す:

アップデート

新しいデータセットを使用した、ベース R でのアプローチ

  df$var2 <-  unlist(lapply(split(df, df$grp),
              function(x) {x$var2 <-0
               indx <- match(unique(x$var1), x$var1)
               x$var2[indx] <- 1
               cumsum(x$var2) }))

  head(df,7)
  #   time grp var1 var2
  # 1    1   1    A    1
  # 2    2   1    B    2
  # 3    3   1    A    2
  # 4    4   1    B    2
  # 5    5   2    A    1
  # 6    6   2    B    2
  # 7    7   2    A    2
于 2014-08-28T16:30:02.097 に答える
1

これは、非常に迅速な data.table を使用した別のソリューションです。

ジェネリック関数

cum_n_distinct <- function(x, na.include = TRUE){
  # Given a vector x, returns a corresponding vector y
  # where the ith element of y gives the number of unique
  # elements observed up to and including index i
  # if na.include = TRUE (default) NA is counted as an 
  # additional unique element, otherwise it's essentially ignored

  temp <- data.table(x, idx = seq_along(x))
  firsts <- temp[temp[, .I[1L], by = x]$V1]
  if(na.include == FALSE) firsts <- firsts[!is.na(x)]
  y <- rep(0, times = length(x))
  y[firsts$idx] <- 1
  y <- cumsum(y)

  return(y)
}

使用例

cum_n_distinct(c(5,10,10,15,5))  # 1 2 2 3 3
cum_n_distinct(c(5,NA,10,15,5))  # 1 2 3 4 4
cum_n_distinct(c(5,NA,10,15,5), na.include = FALSE)  # 1 1 2 3 3

あなたの質問に対する解決策

d_out = df %>%
  arrange(time) %>%
  group_by(grp) %>%
  mutate(var2 = cum_n_distinct(var1))
于 2019-12-04T19:29:32.963 に答える