如何按因子为第一个非NA组创建新列?

时间:2017-11-20 12:20:37

标签: r

Firms    Time     X      Initial X
 1        1        100    100
 1        2        50     100
 1        3        70     100
 2        1        NA     40
 2        2        40     40
 2        3        60     40
 3        1        30     30
 3        2        40     30
 3        3        80     30
 4        1        NA     90
 4        2        NA     90
 4        3        90     90

我想为每家公司创建一个专栏。新列Initial X是开始年份的第一个非NA X

2 个答案:

答案 0 :(得分:1)

以下是基础R解决方案:

initial <- function(x) c(na.omit(x), NA_real_)[1]
transform(DF, Initial_X = ave(X, Firms, FUN = initial))

或者我们可以将initial替换为其中任何一个(最后一个不是基础):

initial <- function(x) sort(x, na.last = TRUE)[1]

initial <- function(x) if (all(is.na(x))) NA_real_ else na.omit(x)[1]

library(zoo)
initial <- function(x) na.locf0(x, fromLast = TRUE)[1]

注意:可重复形式的输入DF为:

Lines <- "
Firms    Time     X      Initial_X
 1        1        100    100
 1        2        50     100
 1        3        70     100
 2        1        NA     40
 2        2        40     40
 2        3        60     40
 3        1        30     30
 3        2        40     30
 3        3        80     30
 4        1        NA     90
 4        2        NA     90
 4        3        90     90"
DF <- read.table(text = Lines, header = TRUE)[1:3] # retain 1st 3 cols only

答案 1 :(得分:0)

library(data.table)

DT <- setDT(df1)
DT[,InitialX := .SD[!is.na(X),X][1],by = Firms]

这里有数据表:.SD选择de = Firms定义的每个broup中的dewole data.table。在此数据表中选择X的非NA(.SD [!is.na(X),X])并取第一个元素([1])。您将它分配给InitialX,它可以为您提供所需的内容:

    Firms Time   X InitialX
 1:     1    1 100      100
 2:     1    2  50      100
 3:     1    3  70      100
 4:     2    1  NA       40
 5:     2    2  40       40
 6:     2    3  60       40
 7:     3    1  30       30
 8:     3    2  40       30
 9:     3    3  80       30
10:     4    1  NA       90
11:     4    2  NA       90
12:     4    3  90       90

这是akrun等效答案,但有数据表