提取每列中的前x个观察值,同时保持R中按行索引

时间:2019-09-28 19:40:15

标签: r

以下代码旨在提取每列的前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)
  })
})

但这不是我猜的最简单的方法...谢谢!

1 个答案:

答案 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")