使用带有NA的行重新塑造数据,以识别新列。

3

I have a dataset in R that looks like this:

DF <- data.frame(name=c("A","b","c","d","B","e","f"),
                 x=c(NA,1,2,3,NA,4,5))

我希望你能将其改造成:

rDF <- data.frame(name=c("b","c","d","e","f"),
                  x=c(1,2,3,4,5),
                  head=c("A","A","A","B","B"))

第一行带有NA的标识新列,并且将该“行值”保持到下一个带有NA的行,然后更改“行值”。

我已经尝试过spreadmelt,但它们没有给我我想要的结果。

library(tidyr)
DF %>% spread(name,x)
library(reshape2)
melt(DF, id=c('name'))

有什么建议吗?

@user20650,你为什么删除了你的解决方案? - David Arenburg
@DavidArenburg,这和Colonel的一样...没有必要在页面上添加混乱的东西 ;) - user20650
@user20650 但是你先发了帖子,而且没有使用包。我必须说你是我在SO上行为的榜样。 - David Arenburg
哈哈...干杯,David。 - user20650
3个回答

5
这里提供一种可能的data.table/zoo软件包组合解决方案。
library(data.table) ; library(zoo)

setDT(DF)[is.na(x), head := name]
na.omit(DF[, head := na.locf(head)], "x")

#    name x head
# 1:    b 1    A
# 2:    c 2    A
# 3:    d 3    A
# 4:    e 4    B
# 5:    f 5    B

或者像@Arun建议的那样,只使用data.table

na.omit(setDT(DF)[, head := name[is.na(x)], by=cumsum(is.na(x))])

1
这里真正酷的是有像 setDT(DF)[is.na(x), head := name, roll=TRUE] 这样的东西... - Arun
1
@Arun 或者 roll=na.locf 可能吗?我最近好像在某个地方看到过。 - David Arenburg

3
你可以尝试以下方法:
library(data.table)
library(magrittr)

split(DF, cumsum(is.na(DF$x))) %>%
    lapply(function(u) transform(u[-1,], head=u[1,1])) %>% 
    rbindlist

#   name x head
#1:    b 1    A
#2:    c 2    A
#3:    d 3    A
#4:    e 4    B
#5:    f 5    B

3

以下是只使用基础R函数的方法:

idx <- is.na(DF$x)
x <- rle(cumsum(idx))$lengths
DF$head <- rep(DF$name[idx], x)
DF[!idx,]
#  name x head
#2    b 1    A
#3    c 2    A
#4    d 3    A
#6    e 4    B
#7    f 5    B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接