在每个字符向量上应用purrr :: map [英] Applying purrr::map over each of a vector of characters

查看:68
本文介绍了在每个字符向量上应用purrr :: map的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力更好地理解purrr :: map函数.假设我有一个简单的字符向量,并且我想运行一些函数,使用每个字符作为输入来输出数据帧.

I'm working on trying to understand the purrr::map function a little better. Let's say I have a simple vector of characters, and I want to run some function that outputs a data frame using each character as an input.

这是一个玩具例子

animals <- c('sheep', 'cow', 'horse')

make_df <- function(x){
    data.frame(r1 = rnorm(1:5), r2 = rnorm(1:5), an = x)
}

这是make_df

> make_df('sheep')
r1          r2           an
-0.18069698 -0.4767575  sheep
0.09580225  0.2785548   sheep
-0.74701529 0.2673391   sheep
-1.62795239 1.0026010   sheep
0.36573951  -0.2323944  sheep

现在,我想为每种动物运行此功能并将每个数据框保存到列表中,然后将该列表放入新的数据框中,其中一列是动物,一列是数据框列表(我将可以和其他tidyverse函数一起使用.

Now, I want to run this function for each animal and save each dataframe to a list, and put that list in a new data frame where one column is the animals and one column is the list of data frames (which I'll use with other tidyverse functions).

我认为做到这一点的方式就像 data.frame(animals = animals) %>% mutate(ldf = map(animals, make_df(.)))

I think the way to do that would be something like data.frame(animals = animals) %>% mutate(ldf = map(animals, make_df(.)))

 data.frame(animals = animals) %>% mutate(ldf = map(animals, make_df(.)))

但这给我一个错误

Error in mutate_impl(.data, dots): Evaluation error: arguments imply differing number of rows: 5, 3. Traceback:

1. data.frame(animals = animals) %>% mutate(ldf = map(animals, make_df(.)))
2. withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
3. eval(quote(`_fseq`(`_lhs`)), env, env)
4. eval(quote(`_fseq`(`_lhs`)), env, env)
5. `_fseq`(`_lhs`)
6. freduce(value, `_function_list`)
7. withVisible(function_list[[k]](value))
8. function_list[[k]](value)
9. mutate(., ldf = map(animals, make_df(.)))
10. mutate.data.frame(., ldf = map(animals, make_df(.)))
11. as.data.frame(mutate(tbl_df(.data), ...))
12. mutate(tbl_df(.data), ...)
13. mutate.tbl_df(tbl_df(.data), ...)
14. mutate_impl(.data, dots)

当然,我可以使用lapply

dfs <- lapply(animals, make_df)

但是如果我尝试将dfs和animal绑定到一个数据帧中,则会出现一个看似相关的错误,同样是关于不同的行数.

But then if I try to bind dfs and animals into one data frame, I get a seemingly related error, again about differing numbers of rows.

 data.frame(animals, dfs)

Error in data.frame(animals, dfs): arguments imply differing number of rows: 3, 5 Traceback:

1. data.frame(animals, dfs)
2. stop(gettextf("arguments imply differing number of rows: %s",   .     paste(unique(nrows), collapse = ", ")), domain = NA)

很明显,我在这里缺少一些基本知识.为什么我不能手动将一个字符列表和一个数据帧列表组合到一个数据帧中,以及我如何滥用purrr::map以便R遇到问题,大概是在我的函数中尝试这样做. >

Clearly, I am missing something fundamental here. Why am I unable to combine a list of characters and a list of data frames into one data frame manually, and how am I misusing purrr::map so that R runs into a problem, presumably trying to do the same within my functions.

推荐答案

您的语法有些偏离,您可以使用map(animals, make_df)map(animals, ~ make_df(.))map的第二个参数必须是一个函数,与lapply:

Your syntax is a little bit off, you'd either use map(animals, make_df) or map(animals, ~ make_df(.)), the second argument of map needs to be a function, which is the same as lapply:

data.frame(animals) %>% mutate(ldf = map(animals, make_df)) %>% as.tibble()
# A tibble: 3 x 2
#  animals                  ldf
#   <fctr>               <list>
#1   sheep <data.frame [5 x 3]>
#2     cow <data.frame [5 x 3]>
#3   horse <data.frame [5 x 3]>

data.frame(animals) %>% mutate(ldf = map(animals, ~ make_df(.))) %>% as.tibble()
# A tibble: 3 x 2
#  animals                  ldf
#   <fctr>               <list>
#1   sheep <data.frame [5 x 3]>
#2     cow <data.frame [5 x 3]>
#3   horse <data.frame [5 x 3]>

或者,如果使用data.frame构造函数,则需要使用I创建列表类型列:

Or if using the data.frame constructor, you need to use I to create a list type column:

data.frame(animals, ldf = I(lapply(animals, make_df)))
#                         ^

这篇关于在每个字符向量上应用purrr :: map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆