2017-10-14 120 views
1

我想编写一个函数,它将数据帧作为输入,并且对于数据帧中的每个数值变量,函数会向用户返回变量的平均值,中位数和四分位间距范围。编写一个传递数据帧的R函数并返回一个列表

的数据帧如下:

'data.frame': 271 obs. of 6 variables: 
$ sample.id: int 1 2 4 5 6 7 8 9 12 13 ... 
$ zip  : int 48504 48507 48504 48507 48505 48507 48507 48503 48507 48505 ... 
$ ward  : int 6 9 1 8 3 9 9 5 9 3 ... 
$ Pb1  : num 0.344 8.133 1.111 8.007 1.951 ... 
$ Pb2  : num 0.226 10.77 0.11 7.446 0.048 ... 
$ Pb3  : num 0.145 2.761 0.123 3.384 0.035 ... 

输出应该是这样的:

$Pb1 
    Mean Median  IQR 
10.76687 3.56400 7.75100 

$Pb2 
    Mean Median  IQR 
10.43467 1.40000 4.50100 

$Pb3 
    Mean Median  IQR 
3.701434 0.839000 2.429500 

这里是我的代码:

df.numeric.summary <- function(data) { 
    for (i in 1:ncol(data)) { 
    if (is.numeric(data[[i]]) == TRUE) { 
     variable_mean <- mean(data[[i]]) 
     variable_median <- median(data[[i]]) 
     variable_IQR <- IQR(data[[i]]) 
     variable_data <- data.frame(Mean = variable_mean, Median = variable_median, IQR = variable_IQR) 
    } 
    } 
    return(variable_data) 
} 

我的代码只能导致Pb3,我认为我不能使用for声明,但我怎么能得到三个变量的价值?另外,如何将结果返回到列表中?

+1

我想你应该在这里重新考虑你接受答案的选择。在for循环中增长数据框是所有R中效率最低的操作之一,它应该永远不会被使用。 –

回答

2

虽然有更好的方法可以做到这样的事情在R(我建议你看一下如何使用lapply,至少在一个其他答案和一个评论中提出),我将专注于您的for-loop方法。

您的错误是您在循环中每次通过时重新创建variable_data。这是因为如果你已经走了:

for (i in 1:3) { 
    x = i 
} 
return(x) # <-- This will return a 3 

的解决方案可能是之前定义variable_data for循环,并使用rbind将追加到它:

df.numeric.summary <- function(data) { 
    variable_data = data.frame(variable_mean = numeric(0), variable_median = numeric(0), variable_IQR = numeric(0)) 
    for (i in 1:ncol(data)) { 
    if (is.numeric(data[[i]]) == TRUE) { 
     variable_mean <- mean(data[[i]]) 
     variable_median <- median(data[[i]]) 
     variable_IQR <- IQR(data[[i]]) 
     variable_data <- rbind(variable_data, data.frame(Mean = variable_mean, Median = variable_median, IQR = variable_IQR)) 
    } 
    } 
    return(variable_data) 
} 

对于一个数据帧转换为列表中,这是一个单独的问题,已经被回答by this stackoverflow question。最流行的答案是:

xy.list <- split(xy.df, seq(nrow(xy.df))) 

其中xy.df是你的数据框的名称。

4

有各种各样的度,你可以简化/折叠这一点,但如何:

df.numeric.val <- function(col) { 
    return(c(mean=mean(col),median=median(col),IQR=IQR(col))) 
} 
df.numeric.summary <- function(data) { 
    numcols <- sapply(data,is.numeric) 
    vals <- lapply(data[numcols],df.numeric.val) 
    return(vals) 
} 
df.numeric.summary(mtcars) 
相关问题