说我有如下数据框:
df <- structure(list(
year = c(2001, 2001, 2002, 2003, 2001, 2002, 2003),
name = c("A", "B", "B", "B", "C", "C", "C"),
revenue = c(10, 20, 30, 40, 30, 40, 50)),
.typeOf = c("numeric", "factor", "numeric"),
row.names = c(NA, -7L),
class = "data.frame")
第一列包含年份,第二列-名称,最后一个-收入。您可能会看到,公司“ A”仅包含第一年的数据,而其余公司具有更多的数据。我希望您为公司“ A”添加新行,并以NA
作为下一年(即2002年和2003年)的收入。为此,我使用以下代码:
df %>%
spread(year, revenue) %>%
gather(year, revenue, 2:ncol(.)) %>%
arrange(name) %>%
View()
它工作得很好,尤其是对于较小的数据集,但是从编程的角度来看,我不确定我的解决方案是否正确。使用melt
,cast(dcast)
或其他方法可能存在更好的解决方案。有什么想法吗?
已编辑:关于如何在/使用管道“%>%”中进行操作的任何想法?
答案 0 :(得分:2)
或者,您可以将expand.grid
中的unique
和 year 中的merge
一起使用,并将df
用于all=TRUE
merge(expand.grid(lapply(df[2:1], unique)), df, all=TRUE)
# name year revenue
#1 A 2001 10
#2 A 2002 NA
#3 A 2003 NA
#4 B 2001 20
#5 B 2002 30
#6 B 2003 40
#7 C 2001 30
#8 C 2002 40
#9 C 2003 50
。
php artisan route:list
答案 1 :(得分:1)
在data.table
中,您可以使用dcast()
进行宽泛转换,同时使用drop = FALSE
(保留空白组)创建一个完整的组集。
setorder( dcast( setDT(df), year + name ~ ., drop = FALSE ), name )[]
# year name .
# 1: 2001 A 10
# 2: 2002 A NA
# 3: 2003 A NA
# 4: 2001 B 20
# 5: 2002 B 30
# 6: 2003 B 40
# 7: 2001 C 30
# 8: 2002 C 40
# 9: 2003 C 50
答案 2 :(得分:1)
另一个data.table
选项:
library(data.table)
setDT(df)
df[CJ(year, name, unique = TRUE), on = c("year", "name")]
# year name revenue
# 1: 2001 A 10
# 2: 2001 B 20
# 3: 2001 C 30
# 4: 2002 A NA
# 5: 2002 B 30
# 6: 2002 C 40
# 7: 2003 A NA
# 8: 2003 B 40
# 9: 2003 C 50