R: Использование аргументов функции для обновления элементов во фрейме данных
Я хочу, чтобы элементы, на которые есть ссылки в моем фрейме данных, были заменены аргументом, который я ввел в функцию, однако в данный момент он просто заменяет элементы аргументом, который я использовал для первоначального определения функции (мне трудно объяснить - надеюсь, мой код и картинки немного прояснят это!)
Project_assign <- function(prjct) {
Truth_vector <- is.element((giraffe[,1]),(prjct[,1]))
giraffe[which(Truth_vector),5] <- 'prjct'
assign('giraffe' , giraffe , envir= .GlobalEnv)
}
Project_assign(spine_hlfs)
Это в основном работает, однако элементы заменяются на prjct вместо spine_hlfs
Если я смогу заставить это работать так, как планировалось, тогда я создам вектор со всеми именами проектов и использую его с этой функцией, что экономит мне много ручной работы каждые несколько месяцев. Я относительно новичок в R, поэтому любые объяснения приветствуются.
2 ответа
Походит на простую замену, основанную на match
записи между (списком) фреймов данных запроса и фреймом данных объекта.
Вот пример, основанный на некоторых смоделированных данных.
Я сначала моделирую данные для предмета dataframe
:
# Sample data
giraffe <- data.frame(
runkeys = seq(1:500),
col1 = runif(500),
col2 = runif(500),
col3 = runif(500),
col4 = runif(500));
Я тогда симулирую runkeys
данные за 2 запроса dataframes
:
spine_hlfs <- data.frame(
runkeys = c(44, 260, 478));
ir_dia <- data.frame(
runkeys = c(10, 20, 30))
Запрос dataframes
хранятся в list
:
lst.runkeys <- list(
spine_hlfs = spine_hlfs,
ir_dia = ir_dia);
Пометить runkeys
записи, присутствующие в любом запросе dataframes
мы можем использовать for
цикл до match
runkeys
записи из каждого запроса dataframe
:
# This is the critical line that loops through the dataframe
# and flags runkeys in giraffe with the name of the query dataframe
for (i in 1:length(lst.runkeys)) {
giraffe[match(lst.runkeys[[i]]$runkeys, giraffe$runkeys), 5] <- names(lst.runkeys)[i];
}
Это выход предмета dataframe
после сопоставления runkeys
записей. Я показываю только те строки, где записи в столбце 5 заменены.
giraffe[grep("(spine_hlfs|ir_dia)", giraffe[, 5]), ];
10 10 0.7401977 0.005703928 0.6778921 ir_dia
20 20 0.7954076 0.331462567 0.7637870 ir_dia
30 30 0.5772808 0.183716142 0.6984193 ir_dia
44 44 0.9701355 0.655736489 0.4917452 spine_hlfs
260 260 0.1893012 0.600140166 0.0390346 spine_hlfs
478 478 0.7655976 0.910946623 0.9779205 spine_hlfs
Насколько я понял намерения ФП из многих комментариев, он хочет обновить giraffe
фрейм данных с именем многих других фреймов данных, где runkey
Матчи.
Это может быть достигнуто путем объединения других фреймов данных в один объект data.table, который обрабатывает имена фреймов данных как данные и, наконец, обновляет giraffe
в соединении.
Пример данных
Согласно ОП, giraffe
состоит из 500 строк и 5 столбцов, в том числе runkey
а также project
, project
инициализируется здесь как символьный столбец для последующего объединения с именами фрейма данных.
set.seed(123L) # required for reproducible data
giraffe <- data.frame(runkey = 1:500,
X2 = sample.int(99L, 500L, TRUE),
X3 = sample.int(99L, 500L, TRUE),
X4 = sample.int(99L, 500L, TRUE),
project = "",
stringsAsFactors = FALSE)
Тогда есть ряд фреймов данных, которые содержат только один столбец runkey
, Согласно ОП, runkey
является несвязным, т. е. объединенным набором всех runkey
не содержит дубликатов.
spine_hlfs <- data.frame(runkey = c(1L, 498L, 5L))
ir_dia <- data.frame(runkey = c(3L, 499L, 47L, 327L))
Предложенное решение
# specify names of data frames
df_names <- c("spine_hlfs", "ir_dia")
# create named list of data frames
df_list <- mget(df_names)
# update on join
library(data.table)
setDT(giraffe)[rbindlist(df_list, idcol = "df.name"), on = "runkey", project := df.name][]
runkey X2 X3 X4 project 1: 1 2 44 63 spine_hlfs 2: 2 73 99 77 3: 3 43 20 18 ir_dia 4: 4 73 12 40 5: 5 2 25 96 spine_hlfs --- 496: 496 75 45 84 497: 497 24 63 43 498: 498 33 53 81 spine_hlfs 499: 499 1 33 16 ir_dia 500: 500 99 77 41
объяснение
setDT()
принуждают giraffe
в data.table
, rbindlist(df_list, idcol = "df.name")
создает объединенную таблицу data.table из списка фреймов данных, заполняя тем самым df.name
столбец с именами элементов списка:
df.name runkey 1: spine_hlfs 1 2: spine_hlfs 498 3: spine_hlfs 5 4: ir_dia 3 5: ir_dia 499 6: ir_dia 47 7: ir_dia 327
Этот промежуточный результат runkey
с giraffe
, project
столбец обновляется с содержанием df.name
только для совпадающих строк.
Альтернативное решение
Это зацикливание df_names
и выполняет повторные объединения, которые обновляют giraffe
на месте:
setDT(giraffe)
for (x in df_names) giraffe[get(x), on = "runkey", project := x]
giraffe[]