Как определить столбцы, которые содержат не зависящие от времени переменные в панели data.frame в R? - PullRequest
0 голосов
/ 01 ноября 2019

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

Есть идеи, как мне это сделать?

example_data <- data.frame(ID = c(1,1,1,2,2,2,3,3,3,3), Age = c(1,2,3,1,2,3,1,2,3,4), Sex = factor(c("m","m","m", "f", "f", "f", "m","m","m","m" )))

    ID Age Sex
1   1   1   m
2   1   2   m
3   1   3   m
4   2   1   f
5   2   2   f
6   2   3   f
7   3   1   m
8   3   2   m
9   3   3   m
10  3   4   m

function_that_finds_the_names(example_data)

вывод должен быть символьным векторным результатом:

[1] "ID"  "Sex"

Я пробовал это

function_that_finds_the_names <- function(example_data){
    list <- split(example_data, as.factor(example_data$ID), drop = TRUE)
    z <- lapply(list, function(x) names(which(sapply(x, function(x) length(unique(x))) == 1))) 
    return(z)
}

function_that_finds_the_names(example_data)
$`1`
[1] "ID"  "Sex"

$`2`
[1] "ID"  "Sex"

$`3`
[1] "ID"  "Sex"

возвращает список с именами для каждого идентификатора, но как извлечь изесть один вектор с одинаковыми именами в каждом элементе списка?

Ответы [ 3 ]

0 голосов
/ 01 ноября 2019

Мы предполагаем, что нужны имена столбцов, столбцы которых постоянны в пределах идентификатора.

Код в вопросе работает, если заменить строку return(z) на:

Reduce(intersect, z)

Мы обсудим другой подход. Для каждого имени столбца получите фрейм данных из двух столбцов, состоящий только из столбца ID и этого столбца. Используйте unique, чтобы удалить дублирующиеся строки, и если в том, что осталось, есть дублированные значения ID, исключите этот столбец. Пакеты не используются.

find_names <- function(data, ID = "ID") {
  const_in_id <- function(x) !anyDuplicated(unique(data[c(ID, x)])[[ID]])
  Filter(const_in_id, names(data))
}


find_names(example_data)
## [1] "ID"  "Sex"
0 голосов
/ 01 ноября 2019

Вы можете сделать следующее, используя data.table. Функция также принимает различные group переменные.

name_fn = function(dt, group){

  require(data.table); setDT(dt)

  tempdt = dt[, lapply(.SD, function(x) length(unique(x))), keyby = group]
  return(c(group, names(which(colSums(tempdt) == nrow(tempdt)))))

}

Вывод:

> name_fn(example_data, 'ID')
[1] "ID"  "Sex"
0 голосов
/ 01 ноября 2019

Это то, что вы хотите?

function_that_finds_the_names <- function(example_data){
  list <- split(example_data, as.factor(example_data$ID), drop = TRUE)
  z <- lapply(list, function(x) names(which(sapply(x, function(x) length(unique(x))) == 1))) 
  return(Reduce(intersect, unique(z)))
}
str(function_that_finds_the_names(example_data))
#  chr [1:2] "ID" "Sex"


return(Reduce(intersect, unique(z))) будет обрабатывать, если ваш список имеет переменную длину.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...