Разделяйте столбцы с постоянными числами и объединяйте их в одну строку в R data.frame - PullRequest
1 голос
/ 09 октября 2019

У меня есть data.frame с именем d. В этом data.frame некоторые столбцы состоят из постоянных чисел в строках первого столбца: study.name (см. Ниже).

Например, столбцы ESL, ESL.1, prof,prof.1 - постоянные числа для всех строк Shin.Ellis, а также константы для всех строк Trus.Hsu и т. д.

Q: In BASE R как я могу разделить такие постоянные переменные, а затем сжать их в одну строку с одним номером?

Мой желаемый вывод показан ниже. Функциональный ответ приветствуется.

d <- read.csv("https://raw.githubusercontent.com/izeh/m/master/irr.csv", h = T)[-(2:3)]

## FIRST 8 ROWS:

#    study.name ESL prof scope type ESL.1 prof.1 scope.1 type.1
# 1  Shin.Ellis   1    2     1    1     1      2       1      1
# 2  Shin.Ellis   1    2     1    1     1      2       1      1
# 3  Shin.Ellis   1    2     1    2     1      2       1      1
# 4  Shin.Ellis   1    2     1    2     1      2       1      1
# 5  Shin.Ellis   1    2    NA   NA     1      2      NA     NA
# 6  Shin.Ellis   1    2    NA   NA     1      2      NA     NA
# 7    Trus.Hsu   2    2     2    1     2      2       1      1
# 8    Trus.Hsu   2    2    NA   NA     2      2      NA     NA

Желаемый результат:

#    study.name ESL prof  ESL.1 prof.1 
# 1  Shin.Ellis   1    2      1      2  
# 2  Trus.Hsu     2    2      2      2
# .     .         .    .      .      . # AND SO ON !!!

Ответы [ 4 ]

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

Вы можете попробовать что-то вроде этого, хотя это кажется немного неуклюжим. В основном, проверьте, какие столбцы имеют постоянные значения по группам для всех групп, сохраните только эти столбцы, а затем сохраните только значения unique (поскольку теперь они постоянны по группам).

d <- read.table(header = TRUE,
text = "study.name ESL prof scope type ESL.1 prof.1 scope.1 type.1
Shin.Ellis   1    2     1    1     1      2       1      1
Shin.Ellis   1    2     1    1     1      2       1      1
Shin.Ellis   1    2     1    2     1      2       1      1
Shin.Ellis   1    2     1    2     1      2       1      1
Shin.Ellis   1    2    NA   NA     1      2      NA     NA
Shin.Ellis   1    2    NA   NA     1      2      NA     NA
  Trus.Hsu   2    2     2    1     2      2       1      1
  Trus.Hsu   2    2    NA   NA     2      2      NA     NA")

is_constant <- function(x) length(unique(x)) == 1L

keep_constants <- function(df, group_col) {
  data_cols <- colnames(df)[setdiff(1:ncol(df), group_col)]
  check_df <- aggregate(df, by = list(df[[group_col]]), FUN = is_constant)
  cols_to_keep <- sapply(check_df[, -1], all)
  unique(df[, cols_to_keep])
}

keep_constants(d, 1)
#>   study.name ESL prof ESL.1 prof.1
#> 1 Shin.Ellis   1    2     1      2
#> 7   Trus.Hsu   2    2     2      2

Созданона 2019-10-09 пакетом представьте (v0.3.0)

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

Может быть, нам понадобится

library(dplyr)
d %>%
   group_by(study.name) %>%
   slice(1)

Или в base R после группировки по параметру 'study.name', получите первую строку, указав na.action = NULL, поскольку значение по умолчанию - na.omit который может опустить любую строку, имеющую NA в любом из столбцов

aggregate(.~ study.name, d, head, 1, na.action = NULL)

Если мы хотим подмножество столбцов

nm1 <- names(which(!colSums(!do.call(rbind, by(d[-1], d$study.name,
     FUN = function(x) lengths(sapply(x, unique)) == 1)))))
unique(d[c("study.name", nm1)])
1 голос
/ 09 октября 2019
d_list <- lapply(split(d,d$study.name), 
                 #Find columns with similar values using sapply and length(unique(cols)) 
                 #then get the 1st row
                 function(x) x[1, sapply(x,function(y) length(unique(y))==1)])
do.call('rbind.data.frame',d_list)

           study.name ESL prof ESL.1 prof.1
Bit.KnoA     Bit.KnoA   1    3     1      3
Bit.KnoB     Bit.KnoB   1    2     1      2
ChandlerA   ChandlerA   1    2     1      2
Mubarak       Mubarak   2   NA     2     NA
SheenA         SheenA   1    2     1      2
Shin.Ellis Shin.Ellis   1    2     1      2
Sun               Sun   2    2     2      2
Trus.Hsu     Trus.Hsu   2    2     2      2
1 голос
/ 09 октября 2019

Если вы просто хотите удалить повторяющиеся значения во всех столбцах, уникальный () является базовым R

unique(d)

РЕДАКТИРОВАТЬ - Спасибо за разъяснения @CalumYou - Я думаю, это то, что OP ищет в базе R.

is_constant = lapply(split(d, d$study.name), function(data){
  unlist(lapply(data,function(col){
    length(unique(col)) == 1
  }))
})
is_constant = as.data.frame(do.call(rbind, is_constant))
all_constant = d[,unlist(lapply(is_constant,all))]
all_constant = unique(all_constant)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...