src hop1 hop2 hop3 hop4 destination
A B C NA NA NA
P Q R S NA NA
H I J K L M
现在我想将此表融化为以下格式
src nn en
A B C
B C C
P Q S
Q R S
R S S
H I M
I J M
J K M
K L M
L M M
我对熔化和重塑有基本的了解,但无法想象如何利用这些功能来实现所需的输出。
您基本上希望收集所有列,按每行分组。然后期待前导值和最后一个值。所以在 dplyr 中是这样的东西:
dat %>%
mutate(row=row_number()) %>%
gather(key, src, -row) %>%
drop_na() %>%
group_by(row) %>%
mutate(nn=lead(src), en=last(src)) %>%
ungroup() %>%
filter(!is.na(nn)) %>%
arrange(row) %>%
select(src, nn, en)
## A tibble: 10 x 3
# src nn en
# <chr> <chr> <chr>
# 1 A B C
# 2 B C C
# 3 P Q S
# 4 Q R S
# 5 R S S
# 6 H I M
# 7 I J M
# 8 J K M
# 9 K L M
#10 L M M
或者在基础 R 中像这样:
tmp <- na.omit(data.frame(row=seq_len(nrow(dat)), src=unlist(dat), stringsAsFactors=FALSE))
tmp$nn <- ave(tmp$src, tmp$row, FUN=function(x) c(tail(x,-1),NA) )
tmp$en <- ave(tmp$src, tmp$row, FUN=function(x) tail(x,1) )
tmp <- tmp[!is.na(tmp$nn),]
tmp[order(tmp$row), c("src","nn","en")]
# src nn en
#src1 A B C
#hop11 B C C
#src2 P Q S
#hop12 Q R S
#hop22 R S S
#src3 H I M
#hop13 I J M
#hop23 J K M
#hop33 K L M
#hop43 L M M
dat
在哪里:
dat <- read.table(text="src hop1 hop2 hop3 hop4 destination
A B C NA NA NA
P Q R S NA NA
H I J K L M", header=TRUE, stringsAsFactors=FALSE)
或者
我们可以使用 base R
中的apply
out <- do.call(rbind, apply(dat, 1, function(x) {
x1 <- na.omit(x)
data.frame(src = x1[-length(x1)], nn = x1[-1], en = x1[length(x1)])
}))
row.names(out) <- NULL
out
# src nn en
#1 A B C
#2 B C C
#3 P Q S
#4 Q R S
#5 R S S
#6 H I M
#7 I J M
#8 J K M
#9 K L M
#10 L M M
或者base R
的另一个选项是使用 max.col
查找最后一个非 NA 元素,使用 rep
复制每行中的最后一个非 NA 元素并创建data.frame
ij <- cbind(seq_len(nrow(dat)), max.col(!is.na(dat), "last"))
v1 <- dat[ij]
i1 <- rowSums(!is.na(dat))
src <- na.omit(c(t(replace(dat, ij, NA))))
nn <- na.omit(c(t(dat)[-1,]))
data.frame(src ,nn, en = rep(v1, i1-1 ))
# src nn en
#1 A B C
#2 B C C
#3 P Q S
#4 Q R S
#5 R S S
#6 H I M
#7 I J M
#8 J K M
#9 K L M
#10 L M M