以下代码旨在提取每列的前x个观察值,它们是跨越不同时间段的时间序列。 (或擦除除每一列中的x个第一个值以外的所有内容……)
第一个值可以是数字,后跟NAs
,只要它是时间序列的开始即可。
至关重要的是,每个值都必须与索引中的位置保持联系(第一列“年份”)
# data example
df <- data.frame("Year" = 1791:1800,
"F1" = c(NA, NA, NA, 1.2,1.3, NA, NA, NA, NA, NA),
"F2" = c(NA, NA, 2.1, 2.2, 2.3, 2.4, 2.5, NA, NA, NA),
"F3" = c(NA, NA, NA, NA, NA, 0.1,0.2,0.3,0.4,0.5),
"F4" = c(NA, 3.1,3.2,3.3,3.4,3.5,3.6,3.7,3.8,3.9))
# Convert the dataframe to a list by column
long <- setNames(lapply(names(df)[-1], function(x) cbind(df[1], df[x])), names(df)[-1])
# and select only the first 3 elements after NAs in each column
mylist <- lapply(long, function(x){
head(na.omit(x), 3)
})
# or in a more concise writing ??
mylist2 <- lapply(df, function(x){
head(na.omit(cbind(df[[1]],x)), 3)
})
# Now ‘mylist’ (or ‘mylist2’) contains several vector of different lengths,
# not very appropriate for dataframe, let's switch to long format dataframe
mydata <- do.call(rbind, lapply(mylist, function(x){
require(reshape2)
melt(x, id.vars="Year")
})
)
# and switch back to regular spreadsheet format
library(tidyverse)
mydataCOL <- spread(mydata, key = "variable", value = "value")
write.table(mydataCOL, “sheet1.txt”)
将其应用于数据框列表(多个Excel文件)很复杂。有没有更简单的方法来实现这一目标?在列表的每个数据框的每一列上执行此类操作:)
我目前正在尝试使用“嵌套” lapply()
:
mylist <- lapply(d, function(x){
lapply(x, function(y){
head(na.omit(cbind(x[[1]],y)), 50)
})
})
但这不是我猜的最简单的方法...谢谢!
答案 0 :(得分:0)
如果您仍在使用tidyverse,为什么不全神贯注Hadley的东西呢?
GetTop <- function(indf){
indf %>%
pivot_longer(-Year,names_to="F") %>%
na.omit() %>%
group_by(F) %>%
top_n(3,wt=-Year) %>%
pivot_wider(names_from="F")
}
现在,如果我们可以为一个数据帧调用它
> mytops <- GetTop(df)
如果您有这些数据帧的列表,则可以使用lapply对每个数据帧执行此操作。
allmytop <- lapply(biglist,FUN=GetTop)
这将为您提供数据帧列表。似乎您也想将它们合并到一个胖数据框中。
fatdf <- lapply(biglist,FUN=GetTop) %>% reduce(full_join,by="Year")