2017-01-17 6 views
2

Я хотел бы добавить столбец, содержащий год (найденный в имени файла) в каждый столбец. Я потратил на это несколько часов, но не могу заставить его работать. Я делаю некоторые простые ошибки?Используйте R, чтобы добавить столбец в несколько фреймов данных, используя lapply

Понятно, что я делаю список файлов, а затем использую lapply для вычисления столбца для каждого файла в списке.

Я использую данные из переписи 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 vs. 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, чтобы я мог выровнять два столбца друг от друга.

+2

Вы перебираете части 'dat', поэтому вам нужно вернуть часть, а не весь' dat' – rawr

+0

. Ваш последний пример также работает. Взгляните на 'my.list' после того, как вы его запустили, -' colnames' изменились. – thelatemail

+0

Хорошо, отлично знать. В последнем примере я искал неправильный файл: vs my.list. Я отредактирую его соответствующим образом. – Mox

ответ

1

Я использую следующий код:

for (i in names.of.objects){ 
    temp <- get(i) 
    # do transformations on temp 
    assign(i, temp) 
} 

Это работает, но, безусловно, не производительный, так как это делает поручение всех данных дважды в вызове по значению способом.

+0

Мне сказали, что «для» есть «не путь R». Это, безусловно, работает, но бит применяемого кода кажется «чище», с меньшим количеством строк. – Mox

Смежные вопросы