使用purrr迭代数据帧中的多个(但不是所有)列

使用purrr迭代数据帧中的多个(但不是所有)列,r,dataframe,dplyr,tidyverse,purrr,R,Dataframe,Dplyr,Tidyverse,Purrr,我正在寻找一种简洁的方式,在一个整洁的管道内同时使用多个立柱。 问题是我不需要处理所有列:只需要处理几个列 library(tidyverse) mtcars <- mtcars %>% rownames_to_column(var = 'car') str(mtcars) 'data.frame': 32 obs. of 12 variables: $ car : chr "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet

我正在寻找一种简洁的方式,在一个整洁的管道内同时使用多个立柱。 问题是我不需要处理所有列:只需要处理几个列

library(tidyverse)
mtcars <- mtcars %>% rownames_to_column(var = 'car')
str(mtcars)

'data.frame':   32 obs. of  12 variables:
 $ car : chr  "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...
库(tidyverse)
mtcars%rownames\u到\u列(变量='car')
str(mtcars)
“data.frame”:32 obs。在12个变量中:
$car:chr“马自达RX4”“马自达RX4 Wag”“Datsun 710”“大黄蜂4路”。。。
$mpg:num2122.821.418.718.1144.324.422.819.2。。。
$cyl:num 6 4 6 8 6 8 4 4 6。。。
$disp:num 160 108 258 360。。。
$hp:num 110 93 110 175 105 245 62 95 123。。。
$drat:num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92。。。
$wt:num 2.62 2.88 2.32 3.21 3.44。。。
$qsec:num 16.51718.619.417。。。
$vs:num 0 1 0 1 0 1 1 1 1。。。
$am:num 11 0 0 0 0 0 0。。。
$gear:num 4 4 3 3 3 4 4 4 4。。。
$carb:num 4 1 2 1 4 2 4。。。
假设我想对列
drat
qsec
gear
执行一些操作。(例如,转换为字符。谁知道为什么)


一个人怎么能不写三次动作呢?也许使用
purr()

这里的两个关键函数是
map\u at
(或者
map\u if
如果我们不知道列,而是知道一些关于列的信息,但不知道我们需要哪些列)和
map\u df
(返回数据帧而不是列表)

不幸的是,我看不到一个结合了两者的函数。但我们可以解决这个问题。在
map\u df
上查看引擎盖下方,它是一个常规的
map
,最后添加了
bind\u rows()

这就是我们所需要的:

mtcars2 <- mtcars %>% 
  map_at(c('drat', 'qsec', 'gear'), as.character) %>% 
  bind_rows()
mtcars2%
地图位于(c('drat','qsec','gear'),作为字符)%>%
绑定_行()

这里的两个关键函数是
map\u at
(或者
map\u if
如果我们不知道列,而是知道一些关于列的信息,但不知道需要哪些列)和
map\u df
(返回数据帧而不是列表)

不幸的是,我看不到一个结合了两者的函数。但我们可以解决这个问题。在
map\u df
上查看引擎盖下方,它是一个常规的
map
,最后添加了
bind\u rows()

这就是我们所需要的:

mtcars2 <- mtcars %>% 
  map_at(c('drat', 'qsec', 'gear'), as.character) %>% 
  bind_rows()
mtcars2%
地图位于(c('drat','qsec','gear'),作为字符)%>%
绑定_行()

在dplyr中尝试在处进行变异:

mtcars %>% mutate_at(c("drat", "qsec", "gear"), as.character)
也可以这样写:

mtcars %>% mutate_at(vars(drat, qsec, gear), as.character)

在dplyr中尝试在处进行变异:

mtcars %>% mutate_at(c("drat", "qsec", "gear"), as.character)
也可以这样写:

mtcars %>% mutate_at(vars(drat, qsec, gear), as.character)

一个基本的解决方案。我们可以使用
lappy
循环遍历列名,并设计一个函数将目标列转换为字符

mtcars[] <- lapply(colnames(mtcars),
                    function(x) {
                      y <- mtcars[[x]]
                      if (x %in% c("drat", "qsec", "gear")){
                        y <- as.character(y)
                      }
                      return(y)
                    })

str(mtcars)
# 'data.frame': 32 obs. of  12 variables:
#   $ car : chr  "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
# $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
# $ disp: num  160 160 108 258 360 ...
# $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
# $ drat: chr  "3.9" "3.9" "3.85" "3.08" ...
# $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
# $ qsec: chr  "16.46" "17.02" "18.61" "19.44" ...
# $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
# $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
# $ gear: chr  "4" "4" "4" "3" ...
# $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

mtcars[]基本的R解决方案。我们可以使用
lappy
循环遍历列名,并设计一个函数将目标列转换为字符

mtcars[] <- lapply(colnames(mtcars),
                    function(x) {
                      y <- mtcars[[x]]
                      if (x %in% c("drat", "qsec", "gear")){
                        y <- as.character(y)
                      }
                      return(y)
                    })

str(mtcars)
# 'data.frame': 32 obs. of  12 variables:
#   $ car : chr  "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
# $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
# $ disp: num  160 160 108 258 360 ...
# $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
# $ drat: chr  "3.9" "3.9" "3.85" "3.08" ...
# $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
# $ qsec: chr  "16.46" "17.02" "18.61" "19.44" ...
# $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
# $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
# $ gear: chr  "4" "4" "4" "3" ...
# $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

mtcars[]您也可以使用
modify
modify_at
purr
modify
函数与
map
类似,只是输出的格式与输入相同

modify_at
的使用方法与@g-grothendieck解决方案中的
mutate_at
相同:

mtcars %>% modify_at(c("drat", "qsec", "gear"), as.character)
如果您使用
magrittr
,您也可以这样做(此项覆盖
mtcars
):

mtcars[,c(“drat”、“qsec”、“gear”)]%%修改(如字符)

您也可以从
purrr
使用
modify
modify\u,除了输出格式与输入格式相同外,
modify
功能与
map
类似

modify_at
的使用方法与@g-grothendieck解决方案中的
mutate_at
相同:

mtcars %>% modify_at(c("drat", "qsec", "gear"), as.character)
如果您使用
magrittr
,您也可以这样做(此项覆盖
mtcars
):

mtcars[,c(“drat”、“qsec”、“gear”)]%%修改(如字符)

我很确定有一个基本的R解决方案。但正如我所想,它比它的整洁的对应物要麻烦一些。是的,我同意。mutate_at和map_at更简洁。我确信有一个基本的R解决方案。但正如我所想,它比它的整洁的对应物要麻烦一些。是的,我同意。mutate_at和map_at更简洁。您正在寻找
modify_at
map
函数族的思想是具有固定的输出,
modify
函数族的思想是具有相同的输出和输入格式。在这种情况下,
mutate_at
也可以正常工作(我认为
modify_at
mutate_at
在data.frames上的行为是相同的,但是
mutate
家族只在data.frames上工作)您正在寻找的
modify_at
map
家族函数的思想是有一个固定的输出,
modify
系列的思想是使输出和输入具有相同的格式。在这种情况下,
mutate_at
也可以正常工作(我认为
modify_at
mutate_at
在data.frames上的行为相同,但
mutate
系列仅在data.frames上工作)