Сводка набора данных с использованием lapply

Это вопрос новичка, однако мне очень трудно понять, как правильно использовать lapply, особенно когда используемый идентификатор не является числовым.

Возможно, есть более эффективные методы, чтобы попытаться найти резюме, которое я имею в виду, но сейчас я пытаюсь использовать его как нельзя лучше. По сути, у меня есть большой df с 17 столбцами. Два столбца - это идентификатор и дата. Не все идентификаторы имеют записанное значение в данном имени столбца. Меня интересует поиск общего числа строк, доступных для каждого столбца, и количества уникальных идентификаторов, существующих для этого столбца. У меня есть пример dput, который проясняет ситуацию. Например, в Var8 доступно только 6 строк данных, в результате - 6 уникальных идентификаторов. Кроме того, Var15 имеет 20 строк и 12 уникальных идентификаторов. Но я хочу знать это для всех Var15. Я могу сделать это вручную, используя

Var8=df[!(is.na(df$Var8)),]
length(df$ID)
length(unique(df$ID)) 
remove(Var8)

Но пытаюсь автоматизировать

lapply(COL.NAMES, function(x){
       temp=df[!(is.na(df$paste(x))),]
       rows=length(temp$ID)
       num_comp=length(unique(temp$ID)) 
       return(rows)
       return(num_comp)
       remove(temp)
})

оставляет меня с ошибкой: попытка применить не-функцию.

COL.NAMES<-c("Var1","Var2","Var3","Var4","Var5","Var6","Var7","Var8","Var9","Var10","Var11","Var12","Var13","Var14","Var15")


structure(list(ID = structure(c(1L, 5L, 6L, 7L, 8L, 9L, 10L, 
11L, 12L, 2L, 3L, 4L, 1L, 5L, 6L, 7L, 8L, 9L, 10L, 11L), .Label = c("Comp1", 
"Comp10", "Comp11", "Comp12", "Comp2", "Comp3", "Comp4", "Comp5", 
"Comp6", "Comp7", "Comp8", "Comp9"), class = "factor"), Date = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L), .Label = c("0/1/2014", "0/1/2015"), class = "factor"), 
    Var1 = c(0.57, 0.34, 0.38, 0.93, 0.54, 0.17, 0.08, 0.28, 
    0.99, 1, 0.61, 0.73, 0.15, 0.09, 0.64, 0.3, 0.12, 0.79, 0.79, 
    0.15), Var2 = c(0.7, 0.77, 0.93, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.46, 0.26), Var3 = c(0.65, 
    0.7, 0.83, 0.7, 0.43, 0.81, 0.21, 0.44, 0.25, 0.77, 0.24, 
    0.29, 0.87, 0.42, 1, NA, NA, NA, NA, 0.79), Var4 = c(1, 0.7, 
    0.69, NA, NA, NA, NA, 0.2, 0.61, 0.89, 0.45, 0.02, 0.97, 
    0.33, 0.34, 0.81, 0.99, 0.35, 0.48, 0.33), Var5 = c(0.47, 
    0.95, 0.38, 0.69, 0.84, 0.21, 0.62, 0.59, 0.45, 0.63, 0.18, 
    0.49, NA, NA, NA, NA, 0.17, 0.15, 0.6, 0.44), Var6 = c(NA, 
    NA, NA, NA, 0.24, 0.07, 0.75, 0.24, 0.82, 0.14, 0.86, 0.63, 
    0.82, 0.92, 0.55, 0.22, 0.87, 0.69, 0.64, 0.73), Var7 = c(0.2, 
    0.11, 0.82, 0.31, 0.97, NA, NA, NA, NA, 0.83, 0.84, 0.81, 
    0.72, 0.36, 0.09, 0.15, 0.46, 0.79, 0.75, 0.39), Var8 = c(0.28, 
    0.55, NA, NA, NA, NA, 0.56, 0.89, 0.92, 0.46, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA), Var9 = c(0.11, 0.36, 1, 0.44, 
    0.53, 0.6, 0.24, 0.56, 0.6, 0.55, 0.55, 0.05, 0.77, 0.9, 
    NA, NA, NA, NA, 0.4, 0.33), Var10 = c(0.74, 0.13, 0.09, 0.61, 
    NA, NA, NA, NA, 0.27, 0.71, 0.56, 0.3, 0.36, 0.44, 0.78, 
    0.9, 0.46, 0.49, 0.87, 0.36), Var11 = c(0.58, 0.99, 0.07, 
    0.83, 0.45, 0.07, 0.16, 0.43, 0.34, 0.31, 0.06, 0.67, 0.02, 
    0.52, 0.19, 0.49, 0.31, 0.02, 0.62, 0.21), Var12 = c(0.93, 
    0.26, 0.77, 0.8, 0.67, 0.83, 0.12, 0.39, 0.78, 0.75, 0.44, 
    NA, NA, NA, NA, 0.42, 0.49, 0.06, 0.8, 0.54), Var13 = c(0.44, 
    0.75, NA, NA, NA, NA, 0.58, 0.3, 0.47, 0.88, 0.36, 0.21, 
    0.87, 0.33, 0.12, 0.31, 0.95, 0.59, 0.18, 0.43), Var14 = c(0.55, 
    0.03, 0.37, 0.66, NA, 0.91, 0.78, 0.84, 0.96, 0.34, 0.25, 
    0.92, 0.71, 0.41, 0.23, 0.54, 0.8, 0.87, 0.3, 0.37), Var15 = c(0.71, 
    0.66, 0.01, 0.7, 0.4, 0.04, 0.3, 1, 0.59, 0.69, 0.88, 0.28, 
    0.44, 0.51, 0.2, 0.17, 0.6, 0.11, 0.85, 0.04)), .Names = c("ID", 
"Date", "Var1", "Var2", "Var3", "Var4", "Var5", "Var6", "Var7", 
"Var8", "Var9", "Var10", "Var11", "Var12", "Var13", "Var14", 
"Var15"), class = "data.frame", row.names = c(NA, -20L))

4 ответа

Решение

Я не уверен, правильно ли я понял, но это может быть вашим решением. х это ваш фрейм данных

try1 <-  function(df){
  temp <- sum(!is.na(df)) ## no of non na entries 
  temp2 <- length(unique(df)) # length unique entries `
  temp <- list("x"=temp,"y"=temp2)
  temp

}

> lapply(x,try1)

Вот data.table soln

library(data.table)
dd <- as.data.table(x)

COL.NAMES<-c("Var1","Var2","Var3","Var4","Var5","Var6","Var7","Var8","Var9","Var10","Var11","Var12","Var13","Var14","Var15")

dd[,lapply(.SD, try1),.SDcols=COL.NAMES]

Я бы посоветовал ознакомиться с обработкой данных с помощью dplyr. Магриттр трубы %>% Внедренный поможет вам разобраться в использовании приложения.

Вот как я бы изменил вашу функцию:

library(dplyr)
tmp<-lapply(COL.NAMES, function(x) df[,c("ID", x)] %>% na.omit) # loop and extract 15 data.frames, each with 2 columns; remove rows with missing value
rows <- sapply(tmp, nrow) 
num_comp <- lapply(tmp, '[[', "ID") %>% lapply(., unique) %>% sapply(., length) #extract only ID column from list of 15 data.frame; loop across each vector to retain unique values; count length of vector.

Другой подход будет

df1 <- data.frame(n_rows = colSums(!is.na(df[,-(1:2)]), na.rm = TRUE), 
                  unique_IDs = sapply(df[,-2], function(i) length(unique(df$ID[!is.na(i)])))[-1])
head(df1)
#     n_rows unique_IDs
#Var1     20         12
#Var2      5          5
#Var3     16         12
#Var4     16         12
#Var5     16         12
#Var6     16         12

Тем не менее, я не использовал lapply, это решение работает

find.uniques<- function(df){
for(i in 1:ncol(df)){   
    uniques<- data.frame()
    uniques[i,1]<- length(!is.na(unique(df[,i])))
    uniques[i,2]<- length(which(!is.na(unique(df[,i]))))
 }
return(uniques)
}

Результатом является data.frame с V1 - сколько строк доступно, V2 - сколько идентификаторов для каждого столбца. Вы также можете return(as.data.frame(t(uniques))) изменить строки на столбцы, чтобы увидеть, что доступно для каждого столбца.

Другие вопросы по тегам