правильно подставить список для замены значений элементов - PullRequest
0 голосов
/ 02 октября 2018

Контекст:
У меня есть список фреймов данных, каждый из которых содержит различные измерения и типы данных столбца.Моя конечная цель - создать именованный вектор, содержащий имя столбца и тип данных, который я могу использовать для явного назначения типов полей для записи таблицы в базу данных - аргумент field.types в DBI::dbWriteTable()

Подход:
Мой текущий метод состоит в том, чтобы извлечь тип данных столбцов в списке, используя class, изменив его так, чтобы я мог использовать его в качестве именованного вектора в аргументе field.types,Мне нужно оценить, действительно ли данные являются целочисленными значениями, и я написал функцию для этого, основанную на этой публикации SO .

Цель:
Я хочуиспользовать вывод списка из моей собственной функции для идентификации и изменения типа данных в именованном векторе, которые являются действительно целочисленными значениями.

Проблема:
Я хочу заменить элементы всписок list_class основан на другом списке list_int с логическими векторами.Я могу сделать эту простую замену / назначение для одного фрейма данных, но у меня возникают проблемы с подмножеством при использовании списка фреймов данных.Я включил воспроизводимый пример и некоторые попытки сделать это ниже.

library(purrr)

list_df <- list(
  df1 = data.frame(v1 = seq(1,10,2),
                   v2 = seq(1,5,1),
                   v3 = seq(1,10,length.out = 5)),
  df2 = data.frame(v2 = c(seq(1,5), NA),
                   v3 = seq(2,7,1),
                   v4 = rep(pi,6)),
  df3 = data.frame(v3 = seq(1,2,length.out = 5),
                   v4 = sample(letters,5),
                   v5 = seq(1,10,2),
                   v6 = seq(1,5,1))
  )

list_class <- map(list_df, ~map_chr(., class)) #named vector

check_int <- function(v) { #check if truly integer value
  if (!is.numeric(v)) FALSE
  else all((v%%1 == 0)[!is.na(v%%1 == 0)])
}

list_int <- map(list_df, ~map_lgl(., ~check_int(.)))

Для одного приведенного ниже фрейма данных работает

list_class[[1]][list_int[[1]]] <- "newdatatype"

И я могу извлечь подмножество, которое мне нужноиз списка, используя базу Map.

Map('[', list_class, list_int)

Ищете понимание того, как собрать все эти части вместе или если мой подход полностью отключен?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Вы можете сделать ...

Map(replace, list_class, list_int, "newdatatatype")
# or
Map(function(x, p) replace(x, p, "newdatatatype"), list_class, list_int)

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

library(magrittr)
list_class %<>% Map(
  f = function(x, p) replace(x, p, "newdatatatype"), 
  p = list_int
)

Примечание: если вы посмотрите на код в replace, вы увидите, что это просто функция-обертка / удобство для того, что код Райана делает большенепосредственно.

0 голосов
/ 02 октября 2018

Простой цикл for должен работать, но вы также можете использовать map2, если хотите решение purrr.

для цикла:

for(i in seq_along(list_class))
  list_class[[i]][list_int[[i]]] <- "newdatatype"

purrr:

map2(list_class, list_int, ~{.x[.y] <- 'newdatatype'; .x})

выход:

# $df1
#            v1            v2            v3 
# "newdatatype" "newdatatype"     "numeric" 
# 
# $df2
#            v2            v3            v4 
# "newdatatype" "newdatatype"     "numeric" 
# 
# $df3
#            v3            v4            v5            v6 
#     "numeric"      "factor" "newdatatype" "newdatatype" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...