R 如何在多列上使用map()函数

R 如何在多列上使用map()函数,r,R,我有一个数据框,看起来像这样: 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 ...

我有一个数据框,看起来像这样:

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中的映射函数,但我不知道怎么做

我们可以使用sub来删除这些字符,方法是匹配+或-后跟数字\\d+,直到字符串的结尾$,转换为数字并将输出分配回原始数据集

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
数据 我们可以使用sub来删除这些字符,方法是匹配+或-后跟数字\\d+,直到字符串的结尾$,转换为数字并将输出分配回原始数据集

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
数据
使用正则表达式解决方案和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"
使用地图

数据
使用正则表达式解决方案和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"
使用地图

数据
与@akrun的答案类似,但使用str_摘录:

如果输出不要求为数字,则只需执行以下操作:

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

数据:


与@akrun的答案类似,但使用str_摘录:

如果输出不要求为数字,则只需执行以下操作:

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

数据:

您可以使用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"
您现在需要的是在维护维度的同时将所有这些设置为数字,因此我们调用数组…、dimdf或结构…,.Dim=dimdf,然后转换为data.frame

您可以使用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"
您现在需要的是在维护维度的同时将所有这些设置为数字,因此我们调用数组…、dimdf或结构…,.Dim=dimdf,然后转换为data.frame

parse_num将提取它找到的第一个数字,忽略其余数字,并转换为数字。我们将它与dplyr::mutate_all一起使用,因此我们将附加tidyverse,它将同时附加readr和dplyr:

parse_num将提取它找到的第一个数字,忽略其余数字,并转换为数字。我们将它与dplyr::mutate_all一起使用,因此我们将附加tidyverse,它将同时附加readr和dplyr:

  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
))
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"
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
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