Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
被R中的map函数所迷惑_R_Purrr - Fatal编程技术网

被R中的map函数所迷惑

被R中的map函数所迷惑,r,purrr,R,Purrr,我使用purrr库在R中编写了以下内容。好吧,一开始比较复杂,但试了20次后,我把它简化为基本的,看看发生了什么 map(list(1:60), function(a) { if (a < 2) { return(1) } else { return(0) }}) 警告信息: 在if(a2)1 else 0)的一种紧凑方式 或者,如果我们正在创建一个包含60个元素的列表,那么as.list将非常有用 map(as.list(1:6

我使用purrr库在R中编写了以下内容。好吧,一开始比较复杂,但试了20次后,我把它简化为基本的,看看发生了什么

map(list(1:60), function(a) { 
    if (a < 2) {
        return(1)
    } else {
        return(0)
    }})
警告信息: 在if(a<2){中:

条件的长度大于1,并且只使用第一个元素

预期结果是一个列表,前两个元素的值为1,其余元素的值为0


这是怎么回事?

如果我们把它放在
列表中,它将被视为一个单独的单元

library(purrr)
map(1:60, ~ if(.x > 2) 1 else 0)
请注意,
~
tidyverse
中是匿名函数调用(
函数(x)if(x>2)1 else 0
)的一种紧凑方式

或者,如果我们正在创建一个包含60个元素的
列表
,那么
as.list
将非常有用

map(as.list(1:60), ~ if(.x > 2) 1 else 0)

对于这一点,我们不需要循环,因为它可以是
unlist
ted,只需与2进行比较(
),就可以创建一个逻辑
向量
,该向量可以通过
as.integer
或(
+
-转换TRUE->1,FALSE->0)强制为二进制

如果输出需要是
列表
,则使用
as.list

as.list(+(unlist(as.list(1:60)) > 2))

在OP的代码中,发生的是

list(1:60)
#[[1]]
#[1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#[43] 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
输入是一个
列表
,只有一个元素的
长度
为60。使用
映射
,它循环通过该单个元素,但
if/else
未矢量化

根据
?控件
,用法为

if(cond)cons.expr else alt.expr

在哪里

cond-长度为1的逻辑向量,不为NA。长度大于1的条件当前可接受,但仅使用第一个元素。当环境变量

这导致
警告
消息,即
if/else
期望
列表
元素的
长度
仅为1。相反,我们可以使用向量化的
ifelse

map(list(1:60), ~ ifelse(.x > 2, 1, 0))
#[[1]]
#[1] 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
或者只提取
列表
元素

ifelse(list(1:60)[[1]] > 2, 1, 0)

我不知道你为什么在
列表中有
1:60
,但是
+(1:60<2)
会给你同样的输出。
map(list(1:60), ~ ifelse(.x > 2, 1, 0))
#[[1]]
#[1] 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
ifelse(list(1:60)[[1]] > 2, 1, 0)