Применить самоопределяемую функцию к списку фреймов данных в R - PullRequest
2 голосов
/ 05 августа 2020

Это продолжение предыдущего моего вопроса: Код в R для условного вычитания столбцов во фреймах данных

Теперь я хочу применить данное решение к моей предыдущей проблеме

cols <- grep('^\\d+$', names(df), value = TRUE)
new_cols <- paste0(cols, '_corrected')
df[new_cols] <- df[cols] - df[paste0('Background_', cols)]
df[c("Wavelength", new_cols)]

для каждого фрейма данных в списке. Я импортирую все листы файла Excel, чтобы каждый лист стал одним фреймом данных в списке с использованием этого кода (любезно предоставлено Прочтите все листы в книге Excel в список R с основным ответом data.frames ):

read_excel_allsheets <- function(filename, tibble = FALSE) {
  sheets <- readxl::excel_sheets(filename)
  x <- lapply(sheets, function(X) readxl::read_excel(filename, sheet = X))
  if(!tibble) x <- lapply(x, as.data.frame)
  names(x) <- sheets
  x
}

mysheets <- read_excel_allsheets(file.choose())

Как мне применить первое поле кода к моему списку фреймов данных?

Я хочу получить что-то вроде этого:

df_1 <- structure(list(Wavelength = 300:301, Background_1 = c(5L, 3L), 
                     `1` = c(11L, 12L), Background_2 = c(4L, 5L), `2` = c(12L, 10L)), 
                class = "data.frame", row.names = c(NA, -2L))

df_2 <- structure(list(Wavelength = 300:301, Background_1 = c(6L, 4L),
                     `1` = c(10L, 13L), Background_2 = c(5L, 6L), `2` = c(11L, 11L),
                     Background_3 = c(4L, 6L), `3` = c(13L, 13L)),
                class = "data.frame", row.names = c(NA, -2L))

df_list <- list(df_1, df_2)

К что-то вроде этого:

df_1_corrected <- structure(list(Wavelength = 300:301, `1_corrected` = c(6L, 9L),
                                 `2_corrected` = c(8L, 5L)),
                class = "data.frame", row.names = c(NA, -2L))

df_2_corrected <- structure(list(Wavelength =300:301, `1_corrected` = c(4L, 9L),
                                 `2_corrected` = c(6L, 5L),
                                 `3_corrected` = c(9L, 7L)),
                class = "data.frame", row.names = c(NA, -2L))

df_corrected_list <- list(df_1_corrected, df_2_corrected)

отрывок фактических данных

Wavelength Background 1        1 Background 2       2 Background 3         3
       300     273290.0 337670.0     276740.0  397530     288500.0  367480.0
       301     299126.7 375143.3     299273.3  432250     310313.3  394796.7

Я читал, что для этого будет использоваться функция lapply, но я никогда не использовал ее раньше, так как я вполне новичку в R. Помощь очень ценится!

1 Ответ

0 голосов
/ 05 августа 2020

Вы можете поместить код в функцию и применить его для каждого фрейма данных в списке, используя lapply:

subtract_values <- function(df) {
  cols <- grep('^\\d+$', names(df), value = TRUE)
  new_cols <- paste0(cols, '_corrected')
  df[new_cols] <- df[cols] - df[paste0('Background ', cols)]
  df[c("Wavelength", new_cols)]
}

lapply(df_list, subtract_values)

#[[1]]
#  Wavelength 1_corrected 2_corrected
#1        300           6           8
#2        301           9           5

#[[2]]
#  Wavelength 1_corrected 2_corrected 3_corrected
#1        300           4           6           9
#2        301           9           5           7
...