2014-03-25 75 views
1

我有一個問題我確定有一個優雅的解決方案,我一直無法找到。通過不同數量的邏輯列過濾數據幀

我有一個函數可以創建一個具有不同邏輯向量集的數據幀。在函數結尾處,我想合併所有現有的邏輯向量。潛在的名字是已知的,但是if語句的各種排列是不可行的。

例如下面的兩個數據表。潛在的邏輯向量是「夜晚」,「寵物」,「上升」,並且從1到3個將存在。我希望代碼可以可靠地結合任何邏輯向量。

我得到儘可能想出匹配的潛在列的名稱,列號的列表,但不能把它帶回家

希望這是明確的,感謝您的幫助

df1 <- structure(list(hour = structure(c(1123624800, 1123628400, 1123632000, 
1123635600, 1123639200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    night = c(FALSE, FALSE, TRUE, TRUE, TRUE), pet = c(TRUE, 
    TRUE, TRUE, TRUE, TRUE)), .Names = c("hour", "night", "pet" 
), row.names = c(NA, 5L), class = "data.frame") 

structure(list(hour = structure(c(1123624800, 1123628400, 1123632000, 
1123635600, 1123639200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    night = c(FALSE, FALSE, TRUE, TRUE, TRUE), pet = c(TRUE, 
    TRUE, TRUE, TRUE, TRUE), rising = c(TRUE, TRUE, FALSE, TRUE, 
    FALSE)), .Names = c("hour", "night", "pet", "rising"), row.names = c(NA, 
5L), class = "data.frame") 


filters <- c("rising", "pet", "night") 
match(filters, names(df))[!is.na(match(filters, names(df)))] 

如果我是寫出來的,我想明確一下代碼做:

return(df1[df1$night & df1$pet, ]) 
return(df2[df2$night & df2$pet $ df2$rising, ]) 

編輯:我要改寫這個有希望更清楚。 我有一個數據幀與多達三個邏輯向量包含各種數據質量過濾器的標誌。例如,三個潛在向量的名稱是「晚上」,「寵物」,「上升」。數據幀將具有1到3個這些向量的某種組合。有時它會有「寵物」和「夜間」,或「夜間」和「上升」,或「寵物」和「上升」,或全部三種... ...

我想返回記錄所有的邏輯向量都是真實的。問題是我不會事先知道哪些矢量存在(這取決於函數調用中的選項),所以我想編碼以便能夠處理所有各種組合。喜歡的東西:

check which logical vectors exist 
return(df[(all existing vectors are true), ] 

如果我只是嘗試

return(df[df$rising & df$pet $ df$night, ]) 

的代碼將失敗,只要這些列中的一個缺失,所以我需要一個更強大的方式來做到這一點。

希望這更清晰!一般來說,如果我不能說出這意味着我在做一些愚蠢的問題...

+0

假設第二個'structure'時,說,'df2',你要建立一個新的'data.frame',結合所有的值從匹配在其他兩個數據框中的列(如果是這樣,那麼可能會產生什麼樣的「NA」?或者,是否需要一個組合向量的命名列表?您希望得到結果的樣本將有助於 – hrbrmstr

回答

2

UPDATE:

df2[Reduce(`&`, df2[sapply(df2, is.logical)]),] 

將返回行的所有邏輯列TRUE。您也可以使用最後描述的apply方法。


您可以Reduce&實現自己的目標:

df1[Reduce(`&`, df1[-1]),] 
#     hour night pet 
# 3 2005-08-10 00:00:00 TRUE TRUE 
# 4 2005-08-10 01:00:00 TRUE TRUE 
# 5 2005-08-10 02:00:00 TRUE TRUE 

上面我們用-1排除第一列。下面我們使用的列清單你filters定義:

df2[Reduce(`&`, df2[filters]),] 
#     hour night pet rising 
# 4 2005-08-10 01:00:00 TRUE TRUE TRUE 

Reduce反覆適用&以對,第二個參數元素(在數據幀中的列)。

或者,你可以使用apply

df2[apply(df2[filters], 1, all),] 
df1[apply(df1[-1], 1, all),] 
+0

第一個解決方案(不包括第一列)可以工作,但我無法讓第二個解決方案工作,但由於這將是一個用戶正在調用的函數,我希望以更強大的方式來識別我已經編輯了我的問題,以便更清楚爲你的幫助! –

+0

@IcebergSlim,你能否提供更清晰你的意思,第二個不工作?它如何失敗?你確定你使用的'df2'和'filters'變量與你問題中的'dput'完全相同嗎?我建議你清理你的工作空間並重新創建'df2'和'filter'。 – BrodieG

+0

@IcebergSlim,查看更新後的答案以解決您的編輯問題。 – BrodieG