首页 > 解决方案 > 计算 sf 对象列表中选定列的平均值并将值存储在数据框中

问题描述

假设我有一个sf对象列表,我想计算所选列的平均值。之后,我想将这些值存储在新数据框中的单独列中。样本数据可以从这里下载。以下是我到目前为止所做的。如何解决这个问题?

 # Now make a list of two sample shapefiles "a" and "b"
myfiles = list.files(path = "~",
                     pattern=".shp$", full.names = TRUE)

# Read each shapefile and return a list of sf objects
listOfShp = lapply(myfiles, st_read)
 
# First make an empty df
time.series = data.frame()
# Start a loop
for (i in listOfShp){
  time.series$Mean.Z = data.frame(mean(i$z)) 
  time.series$Intensity.mean = data.frame(mean(i$V4))
}


Error in `$<-.data.frame`(`*tmp*`, "Mean.Z", value = list(mean.i.z. = -4.19655105979791)) : 
  replacement has 1 row, data has 0

标签: rspatialsf

解决方案


看起来您正在尝试将数据框分配为条目而不是值。你可能想要的是这样的:

time.series <-
  listOfShp %>%
  purrr::map_df(
    function(df_) {
      data.frame(
        Mean.Z = mean(df_$z),
        Intensity.mean = mean(df_$V4)
      )
    }
  )

此解决方案遍历 listOfShp。对于列表中的每个 shapefile 数据框,它应用创建具有两列的数据框的函数。在为列表中的每个元素创建数据框后,它将它们绑定到一个数据框中。

带有文件名的更优雅的解决方案可能是:


# Function that takes as an input a file name and outputs some facts about the
# dataframe:
describe_shapefile <- function(shp_path) {
  sf_df <- st_read(shp_path) %>%
    st_set_geometry(NULL)
  mean_z = mean(sf_df$z)
  int_mean = mean(sf_df$V4)
  data.frame(
    filename = shp_path,
    Mean.Z = mean_z,
    Intensity.mean = int_mean
  )
}

# Apply the function to each file in the list
myfiles %>%
  purrr::map_df(describe_shapefile)

推荐阅读