有什么用?

Ari*_*man 40 r

我正试图处理无处不在的which功能.在我开始阅读问题/答案之前,我从未发现它的必要性.而我仍然没有.

据我了解,which采用布尔向量并返回一个弱的较短向量,其中包含元素的索引,这些索引为true:

> seq(10)
 [1]  1  2  3  4  5  6  7  8  9 10
> x <- seq(10)
> tf <- (x == 6 | x == 8)
> tf
 [1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
> w <- which(tf)
> w
[1] 6 8
Run Code Online (Sandbox Code Playgroud)

那么我为什么要使用which而不是直接使用布尔向量?我可能会看到一些带有巨大载体的记忆问题,因为length(w)<< length(tf),但这并不令人信服.并且帮助文件中有一些选项不会增加我对此功能的可能用途的理解.帮助文件中的示例也没有太大帮助.

为清晰起见编辑 - 我理解which返回索引.我的问题是关于两件事:1)为什么你需要使用索引而不是仅使用布尔选择器向量?和2)什么有趣的行为which可能会使它最好只是用一个量化的布尔比较?

jve*_*ani 26

好的,这是昨晚证明有用的东西:

在给定的值向量中,第3个非NA值的索引是多少?

> x <- c(1,NA,2,NA,3)
> which(!is.na(x))[3]
[1] 5
Run Code Online (Sandbox Code Playgroud)

与DWin的使用略有不同,虽然我会说他的引人注目!

  • 我用它来查找不同向量中的值 - 其长度是没有NA值的x的长度 - 因此逻辑值在那里不起作用. (5认同)

Rei*_*son 20

手册页的标题?which提供了动力.标题是:

哪个指数是TRUE

如果你想知道逻辑向量的哪些元素,我将其解释为可能使用的函数TRUE.这与仅使用逻辑向量本身本质上是不同的.那将选择那些元素,而TRUE不是告诉你它们是哪一个TRUE.

常见用例是在向量中获取最大值或最小值的位置:

> set.seed(2)
> x <- runif(10)
> which(x == max(x))
[1] 5
> which(x == min(x))
[1] 7
Run Code Online (Sandbox Code Playgroud)

这些是如此常用,which.max()which.min()创建:

> which.max(x)
[1] 5
> which.min(x)
[1] 7
Run Code Online (Sandbox Code Playgroud)

但是,请注意,特定表单不是通用表单的准确替换.详情?which.min请见.一个例子如下:

> x <- c(4,1,1)
> which.min(x)
[1] 2
> which(x==min(x))
[1] 2 3
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答.在编辑的最后添加了示例.希望这是正确的礼仪.如果没有,lemme知道,我会恢复. (3认同)
  • 这仍然是我的问题.我之前使用过`x [which.max(x)]`,发现它很方便.但我发现它很方便,因为它保存了输入`x [x == max(x)]`.换句话说,因为它是一个快捷方式,不是因为有某种原因我需要*position*和Boolean.有一个位置向量可以让你超越一个布尔的向量? (2认同)
  • @ gsk3一个原因是DWin提到的'NA`业务.考虑我的例子中的`x`:`x [4] < - NA`然后尝试`x [x == max(x,na.rm = TRUE)]`.有些人会认为回归丑陋中的"NA". (2认同)

42-*_*42- 17

两个非常令人信服的理由不要忘记which:

1)当您使用"["从数据框中提取时,行位置中导致NA的任何计算都将返回一个垃圾行.使用which删除NA.您可以使用subset%in%不会产生同样的问题.

> dfrm <- data.frame( a=sample(c(1:3, NA), 20, replace=TRUE), b=1:20)
> dfrm[dfrm$a >0, ]
      a  b
1     1  1
2     3  2
NA   NA NA
NA.1 NA NA
NA.2 NA NA
6     1  6
NA.3 NA NA
8     3  8
# Snipped  remaining rows
Run Code Online (Sandbox Code Playgroud)

2)何时需要阵列指示灯.


dar*_*zig 12

which可能是有用的(通过保存计算机和人力资源的方式),例如,如果您必须通过给定的变量/列过滤数据框/矩阵的元素,并基于此更新其他变量/列.例:

df <- mtcars
Run Code Online (Sandbox Code Playgroud)

代替:

df$gear[df$hp > 150] <- mean(df$gear[df$hp > 150])
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

p <- which(df$hp > 150)
df$gear[p] <- mean(df$gear[p])
Run Code Online (Sandbox Code Playgroud)

如果你要筛选过滤的元素是什么不能用一个简单的做额外的情况将是&|,例如,当你有更新基于其他数据表的数据帧的某些部分.这样,需要存储(至少临时)过滤元素的索引.

如果你不得不循环思考数据框架/矩阵的一部分或者必须做其他类型的转换需要知道几个案例的索引,那么我想到了另一个问题.例:

urban <- which(USArrests$UrbanPop > 80)
> USArrests[urban, ] - USArrests[urban-1, ]
              Murder Assault UrbanPop  Rape
California       0.2      86       41  21.1
Hawaii         -12.1    -165       23  -5.6
Illinois         7.8     129       29   9.8
Massachusetts   -6.9    -151       18 -11.5
Nevada           7.9     150       19  29.5
New Jersey       5.3     102       33   9.3
New York        -0.3     -31       16  -6.0
Rhode Island    -2.9      68       15  -6.6
Run Code Online (Sandbox Code Playgroud)

对于虚拟示例我很抱歉,我知道将美国最城市化的州与字母表之前的状态进行比较没有多大意义,但我希望这是有道理的:)

检查which.minwhich.max给出一些线索,因为您不需要输入很多,例如:

> row.names(mtcars)[which.max(mtcars$hp)]
[1] "Maserati Bora"
Run Code Online (Sandbox Code Playgroud)

  • 为'urban - 1`例子+1(尽管它是一个非常简单的例子).@ gsk3在某些情况下,您需要访问其位置为其他元素的*位置*的*函数*的元素.布尔向量在那里没有多大帮助.当然,出现这种情况的方式往往取决于你正在做什么.;) (3认同)

Ari*_*man 11

好吧,我找到了一个可能的原因.起初我认为它可能是,useNames选项,但事实证明,简单的布尔选择也是如此.

但是,如果您感兴趣的对象是矩阵,则可以使用该,arr.ind选项将结果作为(行,列)有序对返回:

> x <- matrix(seq(10),ncol=2)
> x
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8
[4,]    4    9
[5,]    5   10
> which((x == 6 | x == 8),arr.ind=TRUE)
     row col
[1,]   1   2
[2,]   3   2
> which((x == 6 | x == 8))
[1] 6 8
Run Code Online (Sandbox Code Playgroud)

这是一个方便的技巧,但似乎没有理由证明它的不断使用.


Nic*_*bbe 7

惊讶没人回答:内存效率怎么样?

如果你有一个非常稀疏的长向量TRUE,那么仅跟踪TRUE值的索引可能会更加紧凑.