从列值创建新的新行

时间:2012-09-12 14:22:25

标签: r loops dataframe

我正在努力解决一件事:我有一个R数据帧,每个人都有个人ID,入职年份和退出年份。它看起来像:

id  Entry  Exit  
1   1988  1990  
2   1986  1987

我需要一个新的数据框,其间隔(入口,出口)扩展到它包含的年份,即我需要这个:

id Year  
1  1988  
1  1989  
1  1990  
2  1986  
2  1987

我无法创造正确的循环,我非常感谢你的帮助 干杯

2 个答案:

答案 0 :(得分:2)

d <- structure(list(id = c(1, 2), Entry = c(1988, 1986), Exit = c(1990, 
                1987)), .Names = c("id", "Entry", "Exit"), row.names = c(NA, 
                                                                                                                      -2L), class = "data.frame")

years <- apply(d, 1, function(x) seq(x[2], x[3]))
ids <- rep(d[, "id"], lapply(years, length))

res <- cbind(ids, unlist(years))
res

# ids     
#[1,]   1 1988
#[2,]   1 1989
#[3,]   1 1990
#[4,]   2 1986
#[5,]   2 1987

答案 1 :(得分:1)

这里有两个选项:

  1. 在apply-style命令中构建data.frame,然后将小dfs堆叠成一个大dfs。
  2. 或者使用apply-style命令处理年份扩展并计算之后需要重复的ID次数。这就是@LucianoSelzer在他优雅的回应中所做的。
  3. 无论哪种方式都可以。这是前者的一个例子。

    dat <- data.frame(id=seq(2),entry=c(88,86),exit=c(90,87))
    res <- apply(dat,1,function(x) data.frame(id=x[1],year=seq(x[2],x[3])) )
    > res
    [[1]]
      id year
    1  1   88
    2  1   89
    3  1   90
    
    [[2]]
      id year
    1  2   86
    2  2   87
    

    res现在是data.frames的列表。然后我们可以组合data.frames:

    library(taRifx)
    > stack(res)
      id year
    1  1   88
    2  1   89
    3  1   90
    4  2   86
    5  2   87
    

    或在基地R:

      

    do.call(rbind,RES)     id年   1 1 88   2 1 89   3 1 90   4 2 86   5 2 87