【发布时间】:2017-01-17 03:46:25
【问题描述】:
我想在每一列中添加一个包含年份(在文件名中找到)的列。我花了几个小时在谷歌上搜索这个,但无法让它工作。我犯了一些简单的错误吗?
从概念上讲,我正在制作一个文件列表,然后使用 lapply 计算列表中每个文件的列。
我正在使用来自 Census OnTheMap. 新鲜下载的数据。所有文件都这样命名:“points_2013”“points_2014”等。使用以下代码读取数据:
library(maptools)
library(sp)
shps <- dir(getwd(), "*.shp")
for (shp in shps) assign(shp, readShapePoints(shp))
# the assign function will take the string representing shp
# and turn it into a variable which holds the spatial points data
我的问题与this one 非常相似,只是我没有文件名列表——我只想从文件名中提取列中的条目。 This thread 有问题,但没有答案。 This person 尝试使用 [[ 而不是 $,但没有运气。 This 似乎暗示故障可能出在 cbind 与 rbind ..不确定。我不想输出到 csv,所以 this 并不完全相关。
This 几乎正是我想要做的。根据我的目的调整该示例中的代码会产生以下结果:
dat <- ls(pattern="points_")
dat
ldf = lapply(dat, function(x) {
# Add a column with the year
dat$Year = substr(x,8,11)
return(dat)
})
ldf
points_2014.shp$Year
但是最后一行还是返回NULL!
来自this thread,我调整了他们的解决方案。省略 do.call 和 rbind,这似乎可行:
lapply(points,
function(x) {
dat=get(x)
dat$year = sub('.*_(.*)$','\\1',x)
return(dat)
})
points_2014.shp$year
但最后一行返回一个空值。
开始怀疑我的 R 是否有问题。我使用this example 对其进行了测试,它可以正常工作,所以问题出在其他地方。
# a dataframe
a <- data.frame(x = 1:3, y = 4:6)
a
# make a list of several dataframes, then apply function
#(change column names, e.g.):
my.list <- list(a, a)
my.list <- lapply(my.list, function(x) {
names(x) <- c("a", "b")
return(x)})
my.list
在本网站的一些帮助下,我的最终代码是:
#-------takes all the points files, adds the year, and then binds them together
points2<-do.call(rbind,lapply(ls(pattern='points_*'),
function(x) {
dat=get(x)
dat$year = substr(x,8,11)
dat
}))
points2$year
names(points2)
不过,它确实使用了 rbind,这在短期内很有帮助。从长远来看,我需要再次拆分它,并使用 cbind,所以我可以将两列相互减去。
【问题讨论】:
-
您正在循环访问
dat的部分内容,因此您需要返回部分而不是整个dat -
你的最后一个例子也有效。运行后查看
my.list-colnames已更改。 -
好的,很高兴知道。在最后一个示例中,我正在查看错误的文件:a vs my.list。我会相应地编辑它。
-
好的,我知道了。我没有指定任何东西来保存我正在使用和绑定的内容。所以它正在运行,但没有修改任何内容。
标签: r function substring lapply