我有一个特定的数据框,可以说:
Site Date Start End Spec1 Spec2
ZR 10.05 10:40 11:40 X1
ZR 10.05 10:40 11:40 X2
ZR 10.05 10:40 11:40 X3
ZR 10.05 10:40 11:40 X1
ZR 10.05 10:40 11:40 X4
ZR 10.05 10:40 11:40 X5
最后它应该看起来像:
ZR
Date 10.05
Start 10:40
End 11:40
Spec1 X1
Spec1 X2
Spec1 X3
Spec2 X1
Spec2 X4
Spec2 X5
有些人有一个很好的主意如何开始?我对每个Spec1和Spec2需要一个新行感到困惑。
测试数据:
structure(list(Site = c("ZR", "ZR", "ZR", "ZR", "ZR", "ZR"),
Date = c("10.05", "10.05", "10.05", "10.05", "10.05", "10.05"
), Start = c("10:40", "10:40", "10:40", "10:40", "10:40",
"10:40"), End = c("11:40", "11:40", "11:40", "11:40", "11:40",
"11:40"), Spec1 = c("X1", "X2", "X3", "", "", ""), Spec2 = c("",
"", "", "X1", "X2", "X3")), class = "data.frame", row.names = c(NA,
-6L))
答案 0 :(得分:1)
我假设您的实际数据中包含多个站点的数据。这是使用tidyverse
的通用解决方案。请注意,不可能有重复的行名,因此我在输出中将它们变成了variable
列-
df %>%
gather(variable, value, -Site) %>%
distinct() %>%
filter(value != "") %>%
rownames_to_column("id") %>%
spread(Site, value) %>%
select(-id)
variable ZR
1 Date 10.05
2 Start 10:40
3 End 11:40
4 Spec1 X1
5 Spec1 X2
6 Spec1 X3
7 Spec2 X1
8 Spec2 X4
9 Spec2 X5
答案 1 :(得分:0)
一种(非一般性!)解决问题的方法是
library(tidyverse)
gather(foo,key = Var, value=ZR, -Site) %>%
filter(ZR!="") %>%
select(-Site) %>%
distinct()
Var ZR
1 Date 10.05
2 Start 10:40
3 End 11:40
4 Spec1 X1
5 Spec1 X2
6 Spec1 X3
7 Spec2 X1
8 Spec2 X4
9 Spec2 X5
但是,在我看来,您希望将Key变量用作行名(?)。这实际上不起作用,因为它包含重复项。而且,我看不出您为什么要这么做的原因?
答案 2 :(得分:0)
这是data.table
library(data.table)
unique(melt(setDT(df1), id.var = "Site",
value.name = 'ZR'))[ZR != ''][, Site := NULL][]
# variable ZR
#1: Date 10.05
#2: Start 10:40
#3: End 11:40
#4: Spec1 X1
#5: Spec1 X2
#6: Spec1 X3
#7: Spec2 X1
#8: Spec2 X2
#9: Spec2 X3
答案 3 :(得分:0)
在基数R中,您可以利用unique()
和lapply()
的列中有唯一值的事实,这为您提供了一个列表。使用do.call(rbind())
方法,您可以将列表的行绑定在一起。与do.call(c())
相似,方法是将需要转换的内容串联起来,以便可以rbind()
与第一部分一起使用。像这样:
var <- c(names(df1)[1:3], rep(names(df1)[5:6], each=3))
ZR <- rbind(do.call(rbind, lapply(df1[, 2:4], unique)),
as.matrix(
do.call(c, lapply(5:6, function(x) df1[, x][df1[, x] != ""])))
)
out1 <- data.frame(var, ZR, row.names=NULL)
给予
> out1
var ZR
1 Site 10.05
2 Date 10:40
3 Start 11:40
4 Spec1 X1
5 Spec1 X2
6 Spec1 X3
7 Spec2 X1
8 Spec2 X4
9 Spec2 X5
或者,如果不需要每个Spec*
和行名而不是ID
变量都需要多余的行,则可以
out2 <- data.frame(rbind(
do.call(rbind, lapply(df1[, 2:4], unique)),
do.call(rbind, lapply(5:6, function(x) paste0(df1[, x][df1[, x] != ""], collapse=", ")))
))
dimnames(out2) <- list(names(df1)[-1], df1[1,1])
给予
> out2
ZR
Date 10.05
Start 10:40
End 11:40
Spec1 X1, X2, X3
Spec2 X1, X4, X5