2011-09-03 15 views
7

Me interesa saber si hay un paquete en R para admitir la manipulación de datos de estilo de cadena de llamadas, como en C#/LINQ, F #? Quiero habilitar el estilo de esta manera:Manipulación de datos en R en el estilo LINQ

var list = new[] {1,5,10,12,1}; 
var newList = list 
    .Where(x => x > 5) 
    .GroupBy(x => x%2) 
    .OrderBy(x => x.Key.ToString()) 
    .Select(x => "Group: " + x.Key) 
    .ToArray(); 
+0

Por favor describa la estructura de newList para los que no se puede ejecutar fácilmente el código – mdsumner

+1

Puede haber, sin embargo sería fuera del estilo R habitual: R proviene de Scheme y tiende a utilizar el estilo funcional 'f (x)' en lugar de 'xf'. Podría agregar algo como esto sin demasiado trabajo: todas las operaciones básicas están definidas, solo en forma funcional. – Owen

Respuesta

11

No sé de uno, pero aquí está el comienzo de lo que podría parecer:

`%then%` = function(x, body) { 
    x = substitute(x) 
    fl = as.list(substitute(body)) 
    car = fl[[1L]] 
    cdr = { 
     if (length(fl) == 1) 
      list() 
     else 
      fl[-1L] 
    } 
    combined = as.call(
     c(list(car, x), cdr) 
    ) 
    eval(combined, parent.frame()) 
} 

df = data.frame(x = 1:7) 
df %then% subset(x > 2) %then% print 

Esto imprime

x 
3 3 
4 4 
5 5 
6 6 
7 7 

Si sigues usando hacks así debería ser bastante simple obtener el tipo de sintaxis que te parezca agradable ;-)

edición: combinado con plyr, esto se convierte no está mal del todo:

(data.frame(
    x = c(1, 1, 1, 2, 2, 2), 
    y = runif(6) 
) 
    %then% subset(y > 0.2) 
    %then% ddply(.(x), summarize, 
      ysum = sum(y), 
      ycount = length(y) 
     ) 
    %then% print 
) 
2

(No es una respuesta. Más un comentario extenso sobre la respuesta de Owen.] La respuesta de Owen me ayudó a comprender lo que buscabas y disfruté mucho leyendo su perspicaz respuesta. Este estilo de "afuera hacia adentro" me recordó un ejemplo en la página de ayuda (Reducir) donde la función funcall se define a continuación, aplica sucesivamente:

## Iterative function application: 
Funcall <- function(f, ...) f(...) 
## Compute log(exp(acos(cos(0)) 
Reduce(Funcall, list(log, exp, acos, cos), 0, right = TRUE) 

Lo que encuentro especialmente interesante acerca de la macro de Owen es que esencialmente redefine el procesamiento de argumentos de las funciones existentes. Traté de pensar en cómo podría proporcionar argumentos a las funciones "interiores" para el enfoque Funcall y luego me di cuenta de que su función% then% ya había ordenado esa tarea. Estaba usando los nombres de las funciones sin sus argumentos más a la izquierda pero con todos sus otros argumentos a la derecha. ¡Brillante!

1

https://github.com/slycoder/Rpipe

c(1,1,1,6,4,3) %|% sort() %|% unique() 
# result => c(1,3,4) 

Es cierto, sería bueno tener una función where aquí, o, alternativamente, para permitir funciones anónimas que se pasan en, pero bueno el código fuente está ahí: tenedor y añadir que si usted quiere.

4

dplyr sintaxis encadenamiento asemeja LINQ (de ejemplo):

flights %>% 
    group_by(year, month, day) %>% 
    select(arr_delay, dep_delay) %>% 
    summarise(
    arr = mean(arr_delay, na.rm = TRUE), 
    dep = mean(dep_delay, na.rm = TRUE) 
) %>% 
    filter(arr > 30 | dep > 30) 

Introduction to dplyr - Chaining