从聚合函数到对应变量和组的数据集的插补方式

时间:2019-05-22 22:25:03

标签: r

我有一个由三组不同的观察值组成的数据集。不幸的是,由于缺少数据,因此我想对不同的变量使用均值插补,并输入相应组的均值代替NA。

function example1() {
  return shouldLoopContinue; // Add your own logic here
}

function example2() {
  for (var x = 1; x <= 2; x++) {
    if (example1()) {
      continue;
    }

    doSomeOtherWork();
  }
}

要计算测验分数意味着我做了:

df<-read.csv(id, test1, test2, test3, groupnumber
1, 9, 1, 3, 1
2, 8, 2, NA, 1
3, NA, 3, NA, 2
4, 1, 3, 4, 2
5, 2, 44, NA, 2
6, 4, 4, 1, 3
7, NA, NA, NA,3 )

如何将这些均值输入各自的组号并测试数据集,如下所示?

mean1<-aggregate(test1~groupnumber, data=df, FUN = mean)
mean2<-aggregate(test2~groupnumber, data=df, FUN = mean)
mean3<-aggregate(test3~groupnumber, data=df, FUN = mean)

3 个答案:

答案 0 :(得分:1)

尝试使用dplyr软件包,mutate_at可以同时修改多列。

library(dplyr)
df %>%
  group_by(groupnumber) %>%
  mutate_at(c("test1", "test2", "test3"), ~ ifelse(is.na(.), mean(., na.rm = 
    TRUE), .))

enter image description here

答案 1 :(得分:0)

Good post关于均值插补的限制和实现

旁边:请提供可复制的数据框,例如(用于您的数据)

df <- data.frame(id=c(1,2,3,4,5,6,7),
                 test1=c(9,8,NA,1,2,4,NA),
                 test2=c(1,2,3,3,44,4,NA),
                 test3=c(3,NA,NA,4,NA,1,NA),
                 groupnumber=c(1,1,2,2,2,3,3))

然后使用for循环可以执行此操作……虽然效果不佳

# For 2:4 where 2,3,4 are the columns with tests 1 2 and 3
for(i in 2:4){

# then for each group number value
  for(j in unique(df$groupnumber)){

# index the positions in the data frame with group number = j and column i [row,column] format
    df[which(df$groupnumber==j) , i][is.na(df[which(df$groupnumber==j) , i])] <- mean(df[which(df$groupnumber==j), i], na.rm = TRUE)
  }
}

答案 2 :(得分:0)

其他答案似乎已经解决了该问题,但是我想提供一个data.table解决方案。感谢@JMilner提供的数据示例。

library(data.table)

rm(list = ls())

df <- data.table(data.frame(
  id = c(1, 2, 3, 4, 5, 6, 7),
  test1 = c(9, 8, NA, 1, 2, 4, NA),
  test2 = c(1, 2, 3, 3, 44, 4, NA),
  test3 = c(3, NA, NA, 4, NA, 1, NA),
  groupnumber = c(1, 1, 2, 2, 2, 3, 3)
))


df[, `:=`(test1 = ifelse(is.na(test1), mean(test1, na.rm = TRUE), test1),
          test2 = ifelse(is.na(test2), mean(test2, na.rm = TRUE), test2),
          test3 = ifelse(is.na(test3), mean(test3, na.rm = TRUE), test3)),
   by = .(groupnumber)]


df

结果:

> df
   id test1 test2 test3 groupnumber
1:  1   9.0     1     3           1
2:  2   8.0     2     3           1
3:  3   1.5     3     4           2
4:  4   1.0     3     4           2
5:  5   2.0    44     4           2
6:  6   4.0     4     1           3
7:  7   4.0     4     1           3

我怀疑还有一些其他data.table技巧可以做到这一点,但这些技巧会更加动态,但这对您在问题中提供的数据有效。

data.table的基本语法是dt[i, j, by],可以用SQL语法来考虑,其中:

iwhere

jselect

bygroup by

有关更多信息,请参见?data.table