подмножество только возможных комбинаций из R data.frame - PullRequest
2 голосов
/ 26 октября 2019

Функция foo заставляет subset всегда включать все значения time в любое подмножество.

Например, если я хочу только подмножество prof == 1 из dat, foo также добавляет time==1; time==2; time==3; time==4 к этому подмножеству.

Но иногда добавляют некоторые значения time(в этом примере time==1 и time==4) заставляет subset выдавать ошибку, потому что нет данных для таких поднаборов.

Мне было интересно, как я мог отфильтровать такие ошибки в моем выводе, т.е. получить только выходные данные для возможных подстановок (здесь time == 2 and 3)?

Примечание: данные - игрушка, функциональное решение приветствуется.

# data.frame:
dat <- data.frame(time = c(1,3,2,4), prof = c(2,1,1,2)) 

# Function:
foo <- function(data, mod){

     tim <- sort(unique(data$time))

        s <- substitute(mod)
        G <- lapply(tim, function(x) bquote(.(s) & time == .(x)))

       lapply(1:length(G), function(i) subset(data, G[[i]]))
}
# EXAMPLE OF USE:
foo(dat, prof == 1) # Error in subset(data, G[[i]]) : 'subset' must be logical

# DESIRED OUTPUT:
 [[1]]
   time prof
 1    2    1

[[2]]
  time prof
1    3    1

Ответы [ 2 ]

1 голос
/ 26 октября 2019

Ошибка, которую вы получаете: 'subset' must be logical, что означает, что subset не знает, что делать с call объектами, созданными bquote. Помещение G[[i]] в eval должно заставить работать:

dat <- data.frame(time = c(1,3,2,4), prof = c(2,1,1,2)) 
data <- dat; mod <- substitute(prof == 1)

foo <- function(data, mod){

    tim <- sort(unique(data$time))

    s <- substitute(mod)
    G <- lapply(tim, function(x) bquote(.(s) & time == .(x)))

    lapply(1:length(G), function(i) subset(data, eval(G[[i]]))) # <- Use `eval`
}

foo(dat, prof == 1)

Вывод:

[[1]]
[1] time prof
<0 Zeilen> (oder row.names mit Länge 0)

[[2]]
  time prof
3    2    1

[[3]]
  time prof
2    3    1

[[4]]
[1] time prof
<0 Zeilen> (oder row.names mit Länge 0)

<0 Zeilen> (oder row.names mit Länge 0) просто говорит, что есть 0 строк. Просто установите поднабор выходного списка, чтобы получить нужные вам фреймы данных.

Я также должен отметить, что ваша функция в основном делает то же самое, что и dat[dat$prof == 1,], поскольку вы сравниваете prof для каждого значения time(он возвращает фрейм данных, а не список, но это довольно незначительная деталь). Я не уверен, что вы запланировали, но я подумал, что должен упомянуть об этом.

0 голосов
/ 26 октября 2019

Подмножество данных, разделение его по элементам времени:

    subset_df <- function(df, prof_no){


      split(df[df$prof == prof_no,], df[df$prof == prof_no, "time"]) 


}

Применение:

subset_df(dat, 1)

Используемые данные:

dat <- data.frame(time = c(1,3,2,4), prof = c(2,1,1,2)) 
...