R Подведение итогов data.frame с последним рядом символов
У меня есть data.frame, состоящий из символьных столбцов и числовых столбцов. Теперь я хотел бы вычислить среднее числовых столбцов и добавить результаты в конец информационного кадра.
class1 1 2 5
class2 2 3 6
class3 2 3 2
в
class1 1 2 1
class2 2 3 6
class3 2 3 2
mean 1.6 2.6 3
Я пытался так с colMeans, но это конфликтует с символьным столбцом, и я получаю следующую ошибку:
Error in colMeans(data, na.rm = FALSE) : 'x' must be numeric
Я также пытался ограничить colMeans частями data.frame с данными [2:4], но затем я пытаюсь добавить строку, так как она не имеет той же длины, что и исходный data.frame.
Спасибо за вашу помощь.
2 ответа
Я согласен с приведенным выше комментарием, что вставлять их в конец вашего фрейма данных не кажется хорошей идеей.
В любом случае, вы можете воспользоваться этой возможностью, чтобы расширить свой R-Pertoire с rapply
str(iris)
# 'data.frame': 150 obs. of 5 variables:
# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
# $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
summary(iris)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50
# 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50
# Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50
# Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
# 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
# Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
rapply(iris, mean, classes = c('numeric','integer'))
# Sepal.Length Sepal.Width Petal.Length Petal.Width
# 5.843333 3.057333 3.758000 1.199333
Но если бы вам пришлось присоединиться к ним, вы могли бы сделать
tmp <- rapply(iris, mean, classes = c('numeric','integer'))
rbind(iris, tmp[match(names(iris), names(tmp))])
tail(rbind(iris, tmp[match(names(iris), names(tmp))]), 5)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 147 6.300000 2.500000 5.000 1.900000 virginica
# 148 6.500000 3.000000 5.200 2.000000 virginica
# 149 6.200000 3.400000 5.400 2.300000 virginica
# 150 5.900000 3.000000 5.100 1.800000 virginica
# 151 5.843333 3.057333 3.758 1.199333 <NA>
Я уже сожалею об изобретении R-Pertoire
Вы можете попробовать это, если вы хотите придерживаться colMeans
попытка до сих пор:
new <- rbind(mydf, c(V1 = "mean", as.list(colMeans(mydf[2:4]))))
new
# V1 V2 V3 V4
# 1 class1 1.000000 2.000000 5.000000
# 2 class2 2.000000 3.000000 6.000000
# 3 class3 2.000000 3.000000 2.000000
# 4 mean 1.666667 2.666667 4.333333
str(new)
# 'data.frame': 4 obs. of 4 variables:
# $ V1: chr "class1" "class2" "class3" "mean"
# $ V2: num 1 2 2 1.67
# $ V3: num 2 3 3 2.67
# $ V4: num 5 6 2 4.33
В зависимости от того, как вы создали свои данные, вам может потребоваться преобразовать "V1" в character
первый:
mydf$V1 <- as.character(mydf$V1)