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 цикл до matchrunkeys записи из каждого запроса 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[]
Другие вопросы по тегам