Извлечение только числовых частей строкового столбца с применением и подразрывом - PullRequest
1 голос
/ 10 апреля 2019

У меня есть фрейм данных dat в R, который выглядит так:

id  x   y                           z
1   0   4 California                15 MSG 2017/11
2   0   1 Nationally Representative 11 MSG 2016/04
3   1   1 Nationally Representative 8 MSG 2016/01
4   0   1 Nationally Representative 1 ASDE 2014/01
5   2   1 Nationally Representative 8 MSG 2016/01
6   0   1 Nationally Representative 5 MSG 2015/07

Теперь я хочу перебрать каждый столбец и сохранить только числовую часть в начале, например, в первой строкепеременная x, я хочу сохранить «4», переменная z я хочу сохранить «15» и т. д.

Я пробовал следующее (то есть поиск с пробелами в каждом столбце и удаление его +часть после пробела):

dat_new = apply(dat, 2, function(x) sub(" .+", "", x)) # searchs for any space and deletes the space + everything after the space
dat_new = as.data.frame(apply(dat_new, 2, as.numeric))

Однако то, что работает для небольшого подмножества данных, например, первых шести строк, в конечном итоге разрывается.То есть мой общий фрейм данных имеет 5100 строк, и применение вышеуказанных функций приводит к тому, что первый столбец («id») становится пустым, это также происходит с некоторыми другими столбцами.В настоящее время я нашел обходной путь с использованием фактического цикла for, , но тем не менее хотел проверить, что не так с моим кодом и есть ли другое элегантное решение.

Типы данных dat:

'data.frame':   5109 obs. of  4 variables:
 $ id: int  1 2 3 4 5 6 7 8 9 10 ...
 $ x : int  0 0 1 0 2 0 1 1 0 0 ...
 $ y : Factor w/ 4 levels "1 Nationally Representative",..: 4 1 1 1 1 1 1 4 1 3 ...
 $ z : Factor w/ 16 levels "1 ASDE 2014",..: 7 3 15 1 15 12 12 8 13 5 ...

Ответы [ 3 ]

1 голос
/ 10 апреля 2019

Используя базу R, мы можем lapply над выбранными столбцами и извлечь числовую часть

cols <- c("y", "z")
df[cols] <- lapply(df[cols], function(x) as.numeric(sub("(^\\d+).*", "\\1", x)))

df
#  id x y  z
#1  1 0 4 15
#2  2 0 1 11
#3  3 1 1  8
#4  4 0 1  1
#5  5 2 1  8
#6  6 0 1  5
1 голос
/ 10 апреля 2019

Реализация apply (может быть медленной):

as.data.frame(apply(dat,2,function(x) gsub("[A-Z].*","",x)))
  d x  y   z
1 1 0 4  15 
2 2 0 1  11 
3 3 1 1   8 
4 4 0 1   1 
5 5 2 1   8 
6 6 0 1   5 
1 голос
/ 10 апреля 2019

Мы можем использовать parse_number из readr в столбцах 'y', 'z', чтобы извлечь первый набор числовой подстроки

library(dplyr)
library(readr)
dat %>%
      mutate_at(vars(y:z), list(~ parse_number(as.character(.))))
#  d x y  z
#1 1 0 4 15
#2 2 0 1 11
#3 3 1 1  8
#4 4 0 1  1
#5 5 2 1  8
#6 6 0 1  5

Или другой вариант - удалить подстроку из пробела, а затем преобразовать в numeric

library(stringr)
dat %>% 
    mutate_at(vars(y:z), list(~ as.numeric(str_remove(., "\\s+.*"))))

Или, используя base R, мы удаляем пробел, за которым следуют другие символы, и преобразуем в числовые значения для столбцов, отличных от первого

dat[-1] <- lapply(dat[-1], function(x) as.numeric(sub("\\s+.*", "", x)))

данные

dat <- structure(list(d = 1:6, x = c(0L, 0L, 1L, 0L, 2L, 0L), y = structure(c(2L, 
 1L, 1L, 1L, 1L, 1L), .Label = c("1 Nationally Representative", 
 "4 California"), class = "factor"), z = structure(c(3L, 2L, 5L, 
 1L, 5L, 4L), .Label = c("1 ASDE 2014/01", "11 MSG 2016/04", "15 MSG 2017/11", 
  "5 MSG 2015/07", "8 MSG 2016/01"), class = "factor")), row.names = c(NA, 
  -6L), class = "data.frame")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...