2015-11-05 82 views
2

我最近發現,在對一個對象(即一個數據框)進行子集化處理後,結果對象可能是在同一行代碼中的「[」它更早!)。這裏是一個例子:嵌套子集與「[」

# 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]返回一個原子向量,然後將其與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 

但我想知道如果我可以使用與[運營商獲得相同的結果「嵌套」子集。我的意思是這樣的代碼:

df2[df2$dept == "econ",][... ,] 

我不知道如何來引用value列在這一點上,因爲第一子集操作df2[df2$dept == "econ",]所得到的數據幀從df2不同的數據幀。我也知道value列是第3列,但我不知道如何使用列索引而不是他們的名稱設置子集條件。

謝謝你的幫助。

+2

FWIW'data.table's非常適合這種類型的操作。 – nrussell

+1

你需要鏈接這個,這意味着包data.table或包dplyr。 – Roland

+0

@nrussell感謝您的建議。我更熟悉'dplyr'軟件包,但在基本R中沒有辦法做到這一點? – SavedByJESUS

回答

5

這裏有一些選擇:

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)] 

這些軟件包提供的鏈接,除了笨拙的基礎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 
+0

非常感謝您的回答。那麼,現在我知道在R基地這是不可能的。 – SavedByJESUS

1

一致認爲,鏈接是必要的:

library(magrittr) 

df %>% 
    `[`(.$dept == "econ",) %>% 
    `[`(.$value == min(.$value),) 

爲什麼不dplyr堅持有關係嗎?

library(dplyr) 

df %>% 
    filter(dept == "econ") %>% 
    filter(value == min(value))