R 按因子填充顺序
我需要用$Country的因子来填充序列中缺失的$Year值。$Count列可以用0填充R 按因子填充顺序,r,R,我需要用$Country的因子来填充序列中缺失的$Year值。$Count列可以用0填充 Country Year Count A 1 1 A 2 1 A 4 2 B 1 1 B 3 1 所以我最终得到了 Country Year Count A 1 1 A 2 1 A 3 0 A 4 2 B 1 1 B
Country Year Count
A 1 1
A 2 1
A 4 2
B 1 1
B 3 1
所以我最终得到了
Country Year Count
A 1 1
A 2 1
A 3 0
A 4 2
B 1 1
B 2 0
B 3 1
希望这是清楚的,伙计们,提前谢谢 库(data.table)
library(data.table)
# d is your original data.frame
setDT(d)
foo <- d[, .(Year = min(Year):max(Year)), Country]
res <- merge(d, foo, all.y = TRUE)[is.na(Count), Count := 0]
#d是您的原始数据帧
setDT(d)
foo类似于@PoGibas的回答:
library(data.table)
# set default values
def = list(Count = 0L)
# create table with all levels
fullDT = setkey(DT[, .(Year = seq(min(Year), max(Year))), by=Country])
# initialize to defaults
fullDT[, names(def) := def ]
# overwrite from data
fullDT[DT, names(def) := mget(sprintf("i.%s", names(def))) ]
给
Country Year Count
1: A 1 1
2: A 2 1
3: A 3 0
4: A 4 2
5: B 1 1
6: B 2 0
7: B 3 1
这概括为拥有更多的列(除了Count
)。我猜类似的功能也存在于“tidyverse”中,其名称类似于“expand”或“complete”。这是一个dplyr
/tidyr
解决方案,使用complete
和full\u seq
:
library(dplyr)
library(tidyr)
df %>% group_by(Country) %>% complete(Year=full_seq(Year,1),fill=list(Count=0))
Country Year Count
<chr> <dbl> <dbl>
1 A 1 1
2 A 2 1
3 A 3 0
4 A 4 2
5 B 1 1
6 B 2 0
7 B 3 1
库(dplyr)
图书馆(tidyr)
df%>%集团(按国家)%>%完成(年份=完整(年份,1),填写=列表(计数=0))
国家年份计数
一一一一
2 A 2 1
3 A 3 0
4 A 4 2
5b11
6B20
7 B 3 1
另一种dplyr
和tidyr
解决方案
library(dplyr)
library(tidyr)
dt2 <- dt %>%
group_by(Country) %>%
do(data_frame(Country = unique(.$Country),
Year = full_seq(.$Year, 1))) %>%
full_join(dt, by = c("Country", "Year")) %>%
replace_na(list(Count = 0))
库(dplyr)
图书馆(tidyr)
dt2%
按(国家)划分的组别%>%
do(数据帧(国家=唯一(.$Country),
年份=全序列(.$Year,1))%>%
完全加入(dt,by=c(“国家”、“年份”))%>%
替换(列表(计数=0))
这里有一种以R为基数的方法,它使用tapply
、do.call
、range
和seq
来计算年份序列。然后从返回的命名列表构造data.frame,将其合并到原始列表中,添加所需的行,最后填充缺少的值
# get named list with year sequences
temp <- tapply(dat$Year, dat$Country, function(x) do.call(seq, as.list(range(x))))
# construct data.frame
mydf <- data.frame(Year=unlist(temp), Country=rep(names(temp), lengths(temp)))
# merge onto original
mydf <- merge(dat, mydf, all=TRUE)
# fill in missing values
mydf[is.na(mydf)] <- 0
另一个基本想法是根据国家进行分割,使用setdiff
从seq(max(Year))
中查找缺少的值,并将它们绑定到原始数据帧中。使用do.call
以rbind
将列表返回到数据帧,即
d1 <- do.call(rbind, c(lapply(split(df, df$Country), function(i){
x <- rbind(i, data.frame(Country = i$Country[1],
Year = setdiff(seq(max(i$Year)), i$Year),
Count = 0));
x[with(x, order(Year)),]}), make.row.names = FALSE))
你的问题是什么?到目前为止你尝试了什么?对不起,结束了;现在重新开放。我想这与通常的expand.grid解决方案有很大不同。这里供参考:并且喜欢这个答案~~@谢谢你!您可以使用by(df,df$Country,function(i)
代替lappy(split(df,df$Country,function(i)…
或tapply
@Onyambu true。我想lappy(split…)
对我来说更自然。谢谢您的建议。
mydf
Country Year Count
1 A 1 1
2 A 2 1
3 A 3 0
4 A 4 2
5 B 1 1
6 B 2 0
7 B 3 1
d1 <- do.call(rbind, c(lapply(split(df, df$Country), function(i){
x <- rbind(i, data.frame(Country = i$Country[1],
Year = setdiff(seq(max(i$Year)), i$Year),
Count = 0));
x[with(x, order(Year)),]}), make.row.names = FALSE))
Country Year Count
1 A 1 1
2 A 2 1
3 A 3 0
4 A 4 2
5 B 1 1
6 B 2 0
7 B 3 1