У меня есть список данных DataFrames (это пространственные датаформы), названные, например, «Map_g1_r1_airport», «map_g1_r1_hotel», "map_g1_r2_bank", "map_g1_r

Это элементы, оцифрованные с нескольких карт. Карты изначально назывались «map_g1_r1», «map_g1_r2».

Я пытаюсь добавить столбец к каждому DataFrame с именем оригинальной карты с использованием цикла.

Вот что я пытаюсь сделать:

map_g1_r1_airport$mapid<-map_g1_r1
With the loop (Unfortunately this does not do what I intend to do. Instead it simply creates a "content" field in the Values board.):
list_df<-c("map_g1_r1_airport", "map_g1_r1_hotel", "map_g1_r2_bank", "map_g1_r2_market")
    for (df in 1:length(list_df)){
      paste(list_df[df],"$mapid<-", 
                    print(content<-gsub("(.*)_.*","\\1", 
                    c(paste(list_df[df]))),sep=""), 
                    quote=FALSE)}

Любая помощь приветствуется!

Вот один пример данных перед изменением:

structure(list(id = c(1, 2, 3), Name = structure(c(1L, 3L, 4L
), .Label = c("A", "B", "C", "D", "E"
), class = "factor"), Year = structure(c(NA_integer_, NA_integer_, 
NA_integer_), .Label = character(0), class = "factor"), geometry = structure(list(
    structure(c(41.4086152370865, 2.44718243982123), class = c("XY", 
    "POINT", "sfg")), structure(c(45.3852740543083, -4.31103098867136
    ), class = c("XY", "POINT", "sfg")), structure(c(38.4200314592624, 
    -6.96113884231683), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", 
"sfc"), precision = 0, bbox = structure(c(xmin = 41.4086152370865, 
ymin = 2.31103098867136, xmax = 45.4200314592624, ymax = -4.44718243982123
), class = "bbox"), crs = structure(list(epsg = NA_integer_, 
    proj4string = NA_character_), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(id = NA_integer_, 
Name = NA_integer_, Year = NA_integer_), .Label = c("constant", 
"aggregate", "identity"), class = "factor"), row.names = c(NA, 
3L), class = c("sf", "data.frame"))

Вот что я хотел бы получить (с mapid map_g1_r1 ):

structure(list(id = c(1, 2, 3), Name = structure(c(1L, 3L, 4L
), .Label = c("A", "B", "C", "D", "E"
), class = "factor"), Year = structure(c(NA_integer_, NA_integer_, 
NA_integer_), .Label = character(0), class = "factor"), geometry = structure(list(
    structure(c(41.4086152370865, 2.44718243982123), class = c("XY", 
    "POINT", "sfg")), structure(c(45.3852740543083, -4.31103098867136
    ), class = c("XY", "POINT", "sfg")), structure(c(38.4200314592624, 
    -6.96113884231683), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", 
"sfc"), precision = 0, bbox = structure(c(xmin = 41.4086152370865, 
ymin = 2.31103098867136, xmax = 45.4200314592624, ymax = -4.44718243982123
), class = "bbox"), crs = structure(list(epsg = NA_integer_, 
    proj4string = NA_character_), class = "crs"), n_empty = 0L), 
    mapid = c("map_g1_r1", "map_g1_r1", "map_g1_r1")), sf_column = "geometry", agr = structure(c(id = NA_integer_, 
Name = NA_integer_, Year = NA_integer_, mapid = NA_integer_), .Label = c("constant", 
"aggregate", "identity"), class = "factor"), row.names = c(NA, 
3L), class = c("sf", "data.frame"))
0
Marcel Campion 15 Янв 2021 в 17:02

2 ответа

Лучший ответ

Вы можете получить все отдельные Dataframes в списке, используя {{x0}}, и добавьте новый столбец с их именем с использованием {{x1}}.

Используя функции tidyverse, вы можете сделать это как:

library(dplyr)
library(purrr)

list_df<-c("map_g1_r1_airport", "map_g1_r1_hotel", "map_g1_r2_bank", "map_g1_r2_market")
tmp <- mget(list_df)

result <- imap(tmp, ~.x %>% mutate(map_id = .y))

result будет иметь все изменения данных Dataframes в списке, если вы хотите, чтобы эти изменения были отражены в исходном объекте, вы можете использовать {{x1}}.

list2env(result, .GlobalEnv)
1
Ronak Shah 18 Янв 2021 в 01:21

Вы можете достичь этого даже без петли.

Сначала я бы начал с создания списка с именами, которые вы хотите видеть в каждом пространственном data.frame. Я предполагаю, что они произошли от названий списка.

mapid = names(list_df)

После этого вы можете использовать mapply для использования функции, которая принимает первый элемент списка (или вектора) и первый элемент другого списка / вектора. Затем он переходит и применяет ту же функцию ко вторым элементам каждого вектора. По сути, это версия lapply с несколькими входами.

Функция, которую мы передадим mapply, это cbind, которая создает, берет два data.frames и объединяет их по столбцам. В этом случае один data.frame будет вашим пространственным объектом, а другой будет вектором с одним единственным элементом: текущим именем карты. cbind естественным образом преобразует это имя в data.frame с одним столбцом и повторит имя, чтобы оно соответствовало количеству строк в пространственном объекте.

final = mapply(cbind, list_df, mapid)

Я не тестировал, но должно работать.

2
JMenezes 15 Янв 2021 в 14:31