编写一个传递数据帧并返回列表的R函数

时间:2017-10-14 20:24:30

标签: r list dataframe

我想编写一个以数据框作为输入的函数,对于数据框中的每个数值变量,函数以列表的形式向用户返回变量的均值,中位数和四分位数范围

数据框如下:

'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语句,但我怎样才能获得三个变量的值?另外,如何将结果返回到列表中?

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:2)

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

您的错误是您在每次循环中从头开始重新创建variable_data。好像你已经离开了:

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

解决方案可能是在for循环之前定义variable_data,并使用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是您的数据框的名称。