Как использовать функцию map () для нескольких столбцов - PullRequest
0 голосов
/ 24 августа 2018

У меня есть фрейм данных, который выглядит следующим образом:

x1   x2   x3     x4   ...
56   45   34    76    ...
56+3 56   42    43    ...
38   53   56-1  55+3  ...
...   ...   ...  ...   ...

В каждой строке более чем в 30 столбцах я хочу сохранить только первые 2 символа, поэтому в основном я хочу удалить все это "+3 "," -1 "и т. Д. Итак, в итоге у меня будет:

x1   x2   x3     x4   ...
56   45   34    76    ...
56   56   42    43    ...
38   53   56    55    ...
...   ...   ...  ...   ...

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

A <- substr(data$x1, start = 1, stop = 2)
data$x1 <- as.factor(A) 

Я думал об использовании функции карты из purrr, но не знаю, как это сделать.

Ответы [ 5 ]

0 голосов
/ 27 августа 2018

readr::parse_num извлечет найденное ею число, игнорирует остальные и преобразует в числовое.Мы используем его с dplyr::mutate_all, поэтому мы добавим tidyverse, к которому будут прикреплены readr и dplyr:

library(tidyverse)
df %>% mutate_all(parse_number)
#   x1 x2 x3 x4
# 1 56 45 34 76
# 2 56 56 42 43
# 3 38 53 56 55
0 голосов
/ 24 августа 2018

Вы можете использовать sub, чтобы захватить только первые два символа, т.е. (^.{2}).* или даже (^..).*, а затем заменить все на захваченную группу, то есть \\1.Теперь это создает символьную матрицу:

sub("(^.{2}).*","\\1",as.matrix(df))
     x1   x2   x3   x4  
[1,] "56" "45" "34" "76"
[2,] "56" "56" "42" "43"
[3,] "38" "53" "56" "55"

Теперь вам нужно сделать все это как числовые, сохраняя размерность, поэтому мы вызываем либо array(...,dim(df)), либо structure(...,.Dim = dim(df)), а затем преобразуем в data.frame()

data.frame(array(as.numeric(sub("(^.{2}).*","\\1",as.matrix(df))),dim(df)))
  X1 X2 X3 X4
1 56 45 34 76
2 56 56 42 43
3 38 53 56 55
0 голосов
/ 24 августа 2018

Используя решение регулярного выражения и apply, мы можем вернуть из каждой ячейки группу чего угодно, за которой следует + или -, за которым следует любое количество цифр.

apply(df,c(1,2),function(x) gsub('(.*)[+-]\\d+','\\1',x))

      x1   x2   x3   x4  
[1,] "56" "45" "34" "76"
[2,] "56" "56" "42" "43"
[3,] "38" "53" "56" "55"

Использование map

library(dplyr)
library(purrr)
#map_df(df,~gsub('(.*)[+-]\\d+','\\1',.x))
df %>% map_df(.,~gsub('(.*)[+-]\\d+','\\1',.x)) %>%
       mutate_at(vars(starts_with("x")),as.factor)  #Change any var start with x to factor

# A tibble: 3 x 4
  x1    x2    x3    x4   
 <fct> <fct> <fct> <fct>
1 56    45    34    76   
2 56    56    42    43   
3 38    53    56    55 

data

df <- read.table(text = "
             x1   x2   x3     x4  
             56   45   34    76    
             56+3 56   42    43    
             38   53   56-1  55+3
",header=T)
0 голосов
/ 24 августа 2018

Аналогично ответу @ akrun, но с str_extract:

library(dplyr)
df %>%
  mutate_all(~ as.numeric(str_extract(., "^\\d+")))

или просто следующим, если вывод не обязательно должен быть числовым:

df %>%
  mutate_all(str_extract, "^\\d+")

Результат:

  x1 x2 x3 x4
1 56 45 34 76
2 56 56 42 43
3 38 53 56 55

Данные:

df <- structure(list(x1 = structure(c(2L, 3L, 1L), .Label = c("38", 
"56", "56+3"), class = "factor"), x2 = c(45L, 56L, 53L), x3 = structure(1:3, .Label = c("34", 
"42", "56-1"), class = "factor"), x4 = structure(c(3L, 1L, 2L
), .Label = c("43", "55+3", "76"), class = "factor")), .Names = c("x1", 
"x2", "x3", "x4"), class = "data.frame", row.names = c(NA, -3L
))
0 голосов
/ 24 августа 2018

Мы можем использовать sub, чтобы удалить эти символы, сопоставив + или - с последующими цифрами (\\d+) до конца ($) строки, преобразовать в numeric и назначитьвывод обратно в исходный набор данных

df[] <- lapply(df, function(x) as.numeric(sub("[+-]\\d+$", "", x)))
df
#  x1 x2 x3 x4
#1 56 45 34 76
#2 56 56 42 43
#3 38 53 56 55

с tidyverse

library(tidyverse)
df %>%
    mutate_all(funs(as.numeric(str_remove(., "[+-]\\d+$"))))

данные

df <- structure(list(x1 = c("56", "56+3", "38"), x2 = c(45L, 56L, 53L
), x3 = c("34", "42", "56-1"), x4 = c("76", "43", "55+3")), 
class = "data.frame", row.names = c(NA, -3L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...