我想知道如何通过编码在最新日期之前提取数据。
cname year x1 x2 x3 x4
Afghanistan 2015 3 2 6 3
Afghanistan 2016 4 7 NA 9
Afghanistan 2017 5 NA NA NA
Albania 2015 2 3 4 3
Albania 2016 2 4 NA NA
Albania 2017 4 NA 8 NA
Algeria 2015 NA NA NA NA
Algeria 2016 NA NA NA NA
Algeria 2017 NA NA NA NA
...
我想得到的答案
cname x1 x2 x3 x4
Afghanistan 5 7 6 9
Albania 4 4 8 3
Algeria NA NA NA NA
...
我想在这里找到答案,但是我发现的只是通过分组对最后的观察结果进行分组。 感谢您的帮助!
答案 0 :(得分:2)
这是zoo
和dplyr
的解决方案:
library(zoo)
library(dplyr)
df <- read.table("clipboard", header=T)
df %>%
group_by(cname) %>%
arrange(year) %>%
mutate_all(funs(na.locf(., na.rm = FALSE))) %>%
filter(year==max(year))
# A tibble: 3 x 6
# Groups: cname [3]
cname year x1 x2 x3 x4
<fct> <int> <int> <int> <int> <int>
1 Afghanistan 2017 5 7 6 9
2 Albania 2017 4 4 8 3
3 Algeria 2017 NA NA NA NA
答案 1 :(得分:1)
这是通过基数R的想法,但是使用coalesce
中的dplyr
来将NA与非NA合并,即
sapply(split(df, df$cname), function(i) { d2 <- data.frame(t(i[order(i$year, decreasing = TRUE), -1]));
do.call(dplyr::coalesce, d2) })
给出,
Afghanistan Albania Algeria [1,] 2017 2017 2017 [2,] 5 4 NA [3,] 7 4 NA [4,] 6 8 NA [5,] 9 3 NA
转置以上结果以获得所需的输出(或将其包装在data.frame
中,或根据需要进行处理),即
t(d3)
[,1] [,2] [,3] [,4] [,5]
Afghanistan 2017 5 7 6 9
Albania 2017 4 4 8 3
Algeria 2017 NA NA NA NA
数据
dput(df)
structure(list(cname = c("Afghanistan", "Afghanistan", "Afghanistan",
"Albania", "Albania", "Albania", "Algeria", "Algeria", "Algeria"
), year = c(2015L, 2016L, 2017L, 2015L, 2016L, 2017L, 2015L,
2016L, 2017L), x1 = c(3L, 4L, 5L, 2L, 2L, 4L, NA, NA, NA), x2 = c(2L,
7L, NA, 3L, 4L, NA, NA, NA, NA), x3 = c(6L, NA, NA, 4L, NA, 8L,
NA, NA, NA), x4 = c(3L, 9L, NA, 3L, NA, NA, NA, NA, NA)), row.names = c(NA,
-9L), class = "data.frame")
答案 2 :(得分:0)
这正在处理您的示例,但我尚未对其他可能性进行测试:
请注意,d
和cname
在调用函数之前必须先由year
和l <- split(d, d$cname) # we split each in a list
l <- lapply(l, function(x) x[, -c(1,2)]) # remove non useful infos
#l <- split(d[, -c(1,2)], d$cname) # this avoids this second line
# this basically seeks for the last non NA value, otherwise uses NA if all are NA
ll <- lapply(l, function(x) {
if (!all(is.na(x))) {
sapply(x, function(y) last(y[!is.na(y)])) # inside each element in the list I search for last non-NA
} else {
NA
}
})
t(as.data.frame(ll))
# x1 x2 x3 x4
# Afghanistan 5 7 6 9
# Albania 4 4 8 3
# Algeria NA NA NA NA
进行排序。
list
基本上,我使用function
,并寻找最后一个非NA值。我鼓励打印每个段落以查看发生了什么。
这可能会变成my_function <- function(data) {
l <- split(data, data$cname)
l <- lapply(l, function(x) x[, -c(1,2)])
ll <- lapply(l, function(x) {
if (!all(is.na(x))) {
sapply(x, function(y) last(y[!is.na(y)]))
} else {
NA
}
})
t(as.data.frame(ll)) # return
}
my_function(d)
# x1 x2 x3 x4
# Afghanistan 5 7 6 9
# Albania 4 4 8 3
# Algeria NA NA NA NA
:
tt<-"cname year x1 x2 x3 x4
Afghanistan 2015 3 2 6 3
Afghanistan 2016 4 7 NA 9
Afghanistan 2017 5 NA NA NA
Albania 2015 2 3 4 3
Albania 2016 2 4 NA NA
Albania 2017 4 NA 8 NA
Algeria 2015 NA NA NA NA
Algeria 2016 NA NA NA NA
Algeria 2017 NA NA NA NA"
d <- read.table(text=tt, header = T)
使用的数据:
{{1}}
答案 3 :(得分:0)
这是一个dplyr
/ tidyr
解决方案。我正在按名称分组,请确保按年份对观察进行排序,然后使用tidyr::fill
将NA
替换为上面的组中最近的非NA
值。
我还建议过滤年份等于最大年份(即最近的年份)的时间,而不是硬编码要保留的年份。这样,如果您拥有比2017年更新的年份的新数据,它就可以很好地扩展。现在,我为每个国家/地区设置了最新年份 的过滤器;但是,如果您需要过滤所有国家的最新年份,请在过滤前向ungroup
添加通话。
library(dplyr)
library(tidyr)
df %>%
group_by(cname) %>%
arrange(year) %>%
fill(x1:x4) %>%
filter(year == max(year)) %>%
select(-year)
#> # A tibble: 3 x 5
#> # Groups: cname [3]
#> cname x1 x2 x3 x4
#> <chr> <int> <int> <int> <int>
#> 1 Afghanistan 5 7 6 9
#> 2 Albania 4 4 8 3
#> 3 Algeria NA NA NA NA
由reprex package(v0.2.1)于2018-11-26创建