使用“[”嵌套子集
Nested subsetting with "["
我最近发现,用“[”对对象(即数据框)进行子集化后,生成的对象可以在同一行代码中用“[”进行子集化(我早该意识到的!) .这是一个例子:
# Create a data frame
df1 <- as.data.frame(matrix(1:9, nrow = 3))
# Take a look at the data frame
df1
V1 V2 V3
1 1 4 7
2 2 5 8
3 3 6 9
# If I want the value which is on the 3rd row and 2nd column
df1[3,2]
[1] 6
# But I could also
df1[,2][3]
[1] 6
关于第二种选择的几句话。 df[,2]
returns 一个原子向量,然后是 df[,2][3]
.
的子集
以下数据框将有助于说明我的问题。这是一个简单的数据框,包含 26 名学生的姓名、他们各自的部门以及一个数值。添加种子编号以实现可重复性。
set.seed(123)
df2 <- data.frame(name = letters, dept = sample(c("econ", "stat", "math"), 26, replace = TRUE), value = runif(26, 0, 100))
head(df2)
name dept value
1 a econ 54.40660
2 b math 59.41420
3 c stat 28.91597
4 d math 14.71136
5 e math 96.30242
6 f econ 90.22990
我想知道谁在econ
部门的价值最低。我首先尝试的是:
df2[df2$dept == "econ" & df2$value == min(df2$value),]
[1] name dept value
<0 rows> (or 0-length row.names)
我花了一段时间才明白我做错了什么,但我终于意识到问题出在我的代码假定总体价值最低的人也来自 econ
部门,事实并非如此(这就是 R
给我的答案)。其实,整体价值最低的人是stat
部门的。
i <- which(df$value == min(df$value))
df[i,]
name dept value
9 i stat 2.461368
当然,我可以通过以下方式轻松找到问题的答案:
df_econ <- df2[df2$dept == "econ",]
df_econ
name dept value
1 a econ 54.40660
6 f econ 90.22990
15 o econ 14.28000
17 q econ 41.37243
18 r econ 36.88455
19 s econ 15.24447
df_econ[df_econ$value == min(df_econ$value),]
name dept value
15 o econ 14.28
但我想知道使用 "nested" 子集和 [
运算符是否可以获得相同的结果。我的意思是这样的代码:
df2[df2$dept == "econ",][... ,]
此时我不知道如何引用 value
列,因为第一个子集操作 df2[df2$dept == "econ",]
的结果数据帧与 df2
不同。我也知道 value
列是第 3 列,但我不知道如何使用列索引而不是它们的名称来设置子集条件。
感谢您的帮助。
同意链接是必要的:
library(magrittr)
df %>%
`[`(.$dept == "econ", ) %>%
`[`(.$value == min(.$value), )
为什么不坚持使用 dplyr?
library(dplyr)
df %>%
filter(dept == "econ") %>%
filter(value == min(value) )
这里有一些选项:
library(dplyr)
# also in @bramtayl's answer:
df2 %>% filter(dept == "econ") %>% filter(value==min(value))
# or
df2 %>% filter(dept == "econ") %>% slice(which.min(value))
# or...
library(data.table)
setDT(df2)[dept == "econ"][value==min(value)]
# or
setDT(df2)[dept == "econ"][which.min(value)]
这些包提供了方便的链接方式,在 base R 中不可用,除了笨拙,比如
subset(subset(df2, dept=="econ"), value == min(value))
可能还有其他软件包,但这两个最近被广泛使用。
评论。如果您只是浏览数据,我建议在 dept
级别进行聚合:
# dplyr:
df2 %>% group_by(dept) %>% slice(which.min(value))
# data.table:
df2[, .SD[which.min(value)], by=dept]
dept name value
1: econ o 14.280002
2: math t 13.880606
3: stat i 2.461368
我最近发现,用“[”对对象(即数据框)进行子集化后,生成的对象可以在同一行代码中用“[”进行子集化(我早该意识到的!) .这是一个例子:
# Create a data frame
df1 <- as.data.frame(matrix(1:9, nrow = 3))
# Take a look at the data frame
df1
V1 V2 V3
1 1 4 7
2 2 5 8
3 3 6 9
# If I want the value which is on the 3rd row and 2nd column
df1[3,2]
[1] 6
# But I could also
df1[,2][3]
[1] 6
关于第二种选择的几句话。 df[,2]
returns 一个原子向量,然后是 df[,2][3]
.
以下数据框将有助于说明我的问题。这是一个简单的数据框,包含 26 名学生的姓名、他们各自的部门以及一个数值。添加种子编号以实现可重复性。
set.seed(123)
df2 <- data.frame(name = letters, dept = sample(c("econ", "stat", "math"), 26, replace = TRUE), value = runif(26, 0, 100))
head(df2)
name dept value
1 a econ 54.40660
2 b math 59.41420
3 c stat 28.91597
4 d math 14.71136
5 e math 96.30242
6 f econ 90.22990
我想知道谁在econ
部门的价值最低。我首先尝试的是:
df2[df2$dept == "econ" & df2$value == min(df2$value),]
[1] name dept value
<0 rows> (or 0-length row.names)
我花了一段时间才明白我做错了什么,但我终于意识到问题出在我的代码假定总体价值最低的人也来自 econ
部门,事实并非如此(这就是 R
给我的答案)。其实,整体价值最低的人是stat
部门的。
i <- which(df$value == min(df$value))
df[i,]
name dept value
9 i stat 2.461368
当然,我可以通过以下方式轻松找到问题的答案:
df_econ <- df2[df2$dept == "econ",]
df_econ
name dept value
1 a econ 54.40660
6 f econ 90.22990
15 o econ 14.28000
17 q econ 41.37243
18 r econ 36.88455
19 s econ 15.24447
df_econ[df_econ$value == min(df_econ$value),]
name dept value
15 o econ 14.28
但我想知道使用 "nested" 子集和 [
运算符是否可以获得相同的结果。我的意思是这样的代码:
df2[df2$dept == "econ",][... ,]
此时我不知道如何引用 value
列,因为第一个子集操作 df2[df2$dept == "econ",]
的结果数据帧与 df2
不同。我也知道 value
列是第 3 列,但我不知道如何使用列索引而不是它们的名称来设置子集条件。
感谢您的帮助。
同意链接是必要的:
library(magrittr)
df %>%
`[`(.$dept == "econ", ) %>%
`[`(.$value == min(.$value), )
为什么不坚持使用 dplyr?
library(dplyr)
df %>%
filter(dept == "econ") %>%
filter(value == min(value) )
这里有一些选项:
library(dplyr)
# also in @bramtayl's answer:
df2 %>% filter(dept == "econ") %>% filter(value==min(value))
# or
df2 %>% filter(dept == "econ") %>% slice(which.min(value))
# or...
library(data.table)
setDT(df2)[dept == "econ"][value==min(value)]
# or
setDT(df2)[dept == "econ"][which.min(value)]
这些包提供了方便的链接方式,在 base R 中不可用,除了笨拙,比如
subset(subset(df2, dept=="econ"), value == min(value))
可能还有其他软件包,但这两个最近被广泛使用。
评论。如果您只是浏览数据,我建议在 dept
级别进行聚合:
# dplyr:
df2 %>% group_by(dept) %>% slice(which.min(value))
# data.table:
df2[, .SD[which.min(value)], by=dept]
dept name value
1: econ o 14.280002
2: math t 13.880606
3: stat i 2.461368