2016-07-14 2 views
0

Я пытаюсь найти элегантное решение проблемы без сложного подмножества и/или линейной итерации. Я объясню, например:Совокупные условные операторы

# Load data 
df1 <- mtcars 

# Can aggregate with simple math functions i.e. mean or sum 
hp_by_cyl <- aggregate(hp ~ cyl, data=df1, mean) 
> hp_by_cyl 
    cyl  hp 
1 4 82.63636 
2 6 122.28571 
3 8 209.21429 

Ok. Но в моих действительно более сложных данных я хочу объединить логическое значение - т. Е. Если x истинно для любой строки, принадлежащей категории A, тогда y = 1. Таким образом, чтобы продлить мой пример, я могу создать столбец с логическими переменным:

df1$logic <- ifelse(df1$gear==4 & df1$hp < 150, 1, 0) 
# How do I aggregate the logical values levels of cyl to answer yes/no 
# if any car with x cylinders has 4 gears and < 150 hp ? 
# So I want an finished table like this: 
cyl  logic 
4  1 
6  1 
8  0 

Так что мой вопрос в том, как использовать агрегат (или заменяющий) команду для создания таблицы, как это? т. Е. Чтобы объединить логический статус, а не числовое значение?

мне также нужно иметь дело с закодированными недостающих значений и в действительности так, чтобы эмулировать, что сложность Сделаю одно из логики-х 99:

df1[5, ]$logic <- 99 

Если для данного уровня cyl один значение равно 1, 99 можно пренебречь - если, однако, все остальные равны 0, то агрегат должен быть равен 99.

Извинения, если есть простой ответ, который я не вижу в своих реальных данных, кажется сложным. Я мог взломать неприятное решение, но я знаю, что он будет очень медленным, и у меня есть набор данных размера 14000 X 140. Спасибо заранее все.

+3

В чем проблема? – Carl

+0

Я понятия не имею, как закодировать его для создания сводной таблицы, которую я хочу. Отредактировано для clariaty – user2498193

ответ

1

Во-первых, не беспокойтесь о 0/1/99, просто оставьте его ИСТИНА/ЛОЖЬ/NA.

df1$logic <- df1$gear==4 & df1$hp < 150 

Тогда просто агрегировать с any или tapply.

aggregate(logic ~ cyl, data=df1, any) 
## cyl logic 
## 1 4 TRUE 
## 2 6 TRUE 
## 3 8 FALSE 

with(df1, tapply(logic, cyl, any)) 
## 4  6  8 
## TRUE TRUE FALSE 

plyr пакет, в частности, функция ddply, это еще один вариант, что многие люди находят более интуитивным.

library(plyr) 
ddply(df1, ~cyl, summarize, isany = any(gear==4 & hp < 150)) 
## cyl isany 
## 1 4 TRUE 
## 2 6 TRUE 
## 3 8 FALSE 
+0

Привет, Аарон. Хм, да, это может сработать, я попробую и дам вам знать. Изменение 0/1/99 может быть сложным, поскольку материал зависит от него, и мне может потребоваться провести различие между фактическими NA и закодированными промахами. Я также придумал другое решение, но это не так чисто. 'result <- aggregate (логический ~ cyl, data = df1, sum); результат <- ifelse (результат> 99, 1, результат) '. Это зависит от того, что, конечно, не 99! Так как я говорю не так чисто, как ваш – user2498193

+0

Вы должны иметь дело с вашими различными недостатками при создании своего логического столбца, чтобы сам логический столбец мог быть TRUE/FALSE/NA. – Aaron

+0

Если у меня пока нет ошибок, это не должно возникать ... Поэтому попробуйте свой метод в реальных данных, но результат будет «.Primitive (« any »)» для каждой переменной группировки. Не знаю, почему я не вижу никакой очевидной причины, но я все еще изучаю ее. EDIT: ok исправил это, вытащив 'function (x)', который я оставил по какой-то причине. Хорошо спасибо, это решает мою проблему !! – user2498193

2

Я думаю, что это то, что вы хотите:

aggregate(hp~cyl,data=mtcars,function(x) ifelse(mean(x)<150,1,0)) 

редактировать: dplyr ваш друг:

mtcars %>% group_by_(~cyl) %>% summarise_(logic=~ifelse(mean(hp)<150 & sum(wt)>3,1,0)) 

Это более сложное логическое утверждение так что надеюсь, что помогает. aggregate не лучший подход, если вы хотите обрабатывать более двух переменных за раз.

+0

Работает в примере с игрушкой - проверит основные данные и вернется с подтверждением/осложнениями! Спасибо за то, что вы уточнили мой вопрос и ответ! – user2498193

+2

'as.integer (mean (x) <150)' может заменить 'ifelse()' для двоичных результатов и является более эффективным. –

+0

На самом деле нет - опять смотрю - это не то же самое. В среднем вы сделали один тест. Это работает, потому что пример груб, но это не то, как я поставил его выше, где я сознательно установил столбец логических значений. В реальных данных столбец «логика» является результатом целой работы и не может быть упрощен, так как вы сделали это здесь – user2498193

Смежные вопросы