R:如何将单个值传播到整个列?

时间:2016-10-18 12:55:13

标签: r dplyr

考虑以下df,

group = c('A','A','A','B','B','B','C','C')
time = c(-1,0,2,0,4,0,3,5)
value = seq(1:8)

df <- data.frame(group,time,value)

> df
  group time value
1     A   -1     1
2     A    0     2
3     A    2     3
4     B    0     4
5     B    4     5
6     B    0     6
7     C    3     7
8     C    5     8

我希望,对于每个group,在value时创建一个包含time == 0的第一个非缺失值的列。当然,对于每组中的每一行,将重复该值。换句话说,预期的输出是

> df
  group time value output
1     A   -1     1      2
2     A    0     2      2
3     A    2     3      2
4     B    0     4      4
5     B    4     5      4
6     B    0     6      4
7     C    3     7     NA
8     C    5     8     NA

如何使用dplyr执行此操作?类似的东西:

df %>%
  mutate(output = coalesce(ifelse(time== 0, value, NA)) ) 

没有做到这一点。

非常感谢!

3 个答案:

答案 0 :(得分:2)

df%>%
  group_by(group)%>%
  mutate(output=value[time==0][1])
  #we take the first non missing match
   group  time value output
  <fctr> <dbl> <dbl>  <dbl>
1      A    -1    10     23
2      A     0    23     23
3      A     2     5     23
4      B     0    22     22
5      B     4    11     22

编辑: 如果没有time==0

  group time value
1     A   -1    10
2     A    0    23
3     A    2     5
4     B    0    22
5     B    4    11
6     C    1    10

我们使用

df%>%group_by(group)%>%
  mutate(output=ifelse(length(value[time==0][1])>0,value[time==0][1],NA))
   group  time value output
  <fctr> <dbl> <dbl>  <dbl>
1      A    -1    10     23
2      A     0    23     23
3      A     2     5     23
4      B     0    22     22
5      B     4    11     22
6      C     1    10     NA

编辑2:同一组的值为多个0&#c>

  group  time value output
  <fctr> <dbl> <int>  <int>
1      A    -1     1      2
2      A     0     2      2
3      A     2     3      2
4      B     0     4      4
5      B     4     5      4
6      B     0     6      4
7      C     3     7     NA
8      C     5     8     NA

答案 1 :(得分:2)

你可以在基础R:

中做到这一点
df$output <- df[df$time==0,]$value[as.numeric(df$group)]

#  group time value output
#1     A   -1    10     23
#2     A    0    23     23
#3     A    2     5     23
#4     B    0    22     22
#5     B    4    11     22

如果没有time=0没有任何变化,它也有效。

以下是它的工作原理:

  • df[df$time==0,]$value:获取value行的time=0列,而vec依次是自身的向量。为了说明,我们将它命名为as.numeric(df$group)
  • vec:重复c(2,3)[c(1,1,1,1,2,2)]中的值。例如:2 2 2 2 3 3会为您提供static

答案 2 :(得分:2)

以下是使用data.table

的选项
library(data.table)
setDT(df)[, output := value[time==0][1L], by = group]
df
#    group time value output
#1:     A   -1     1      2
#2:     A    0     2      2
#3:     A    2     3      2
#4:     B    0     4      4
#5:     B    4     5      4
#6:     B    0     6      4
#7:     C    3     7     NA
#8:     C    5     8     NA