Как добавить строку в фрейм данных и избежать «нечислового аргумента для бинарного оператора» - PullRequest
1 голос
/ 23 октября 2019

У меня есть датафрейм. Я хочу нормализовать столбцы 2 и 3, разделив их на максимальное значение столбцов 2 и 3.

> testdf<- data.frame("a"=c("b",2), "b"=2:3, "c"=3:4, "d"=4:5, stringsAsFactors = F)
> testdf
  a b c d
1 b 2 3 4
2 2 3 4 5

> testdf[2:3]<-testdf[2:3] / do.call(pmax, testdf[2:3])
> testdf
  a         b c d
1 b 0.6666667 1 4
2 2 0.7500000 1 5

Заметьте, как df содержит сочетание числовых и строковых значений? Теперь я хочу добавить строку с большим количеством данных. Если первый элемент добавленной строки является строкой, код выдает ошибку.

> testdf<- data.frame("a"=c("b",2), "b"=2:3, "c"=3:4, "d"=4:5, stringsAsFactors = F)
> testdf
  a b c d
1 b 2 3 4
2 2 3 4 5
> testdf<- testdf %>% rbind(c("a",6,7,8))
> testdf
  a b c d
1 b 2 3 4
2 2 3 4 5
3 a 6 7 8
> testdf[2:3]<-testdf[2:3] / do.call(pmax, testdf[2:3])
Error in FUN(left, right) : non-numeric argument to binary operator

Если вместо этого я использую только числовые значения, это работает.

> testdf<- data.frame("a"=c("b",2), "b"=2:3, "c"=3:4, "d"=4:5, stringsAsFactors = F)
> testdf
  a b c d
1 b 2 3 4
2 2 3 4 5
> testdf<- testdf %>% rbind(c(5,6,7,8))
> testdf
  a b c d
1 b 2 3 4
2 2 3 4 5
3 5 6 7 8
> testdf[2:3]<-testdf[2:3] / do.call(pmax, testdf[2:3])
> testdf
  a         b c d
1 b 0.6666667 1 4
2 2 0.7500000 1 5
3 5 0.8571429 1 8

Любая помощь в том, почему это происходит, очень ценится. Мне нужно иметь возможность добавлять строки, содержащие текст и цифры, сохраняя при этом код работоспособным. Я предполагаю, что я испортил типы, но я не мог понять, как.

Ответы [ 2 ]

1 голос
/ 24 октября 2019

Когда вы делаете rbind(c("a",6,7,8)), вы фактически делаете rbind(c("a","6","7","8")), тем самым превращая все в символ testdf. Это связано с тем, что вектор (c(...) или отдельные столбцы testdf) может содержать данные только одного типа, и R попытается сделать это при размещении всех данных. В этом случае character будет хранить все данные, но, например, numeric избавит от букв.

Просто используйте testdf %>% rbind(list("a",6,7,8)) вместо testdf %>% rbind(c("a",6,7,8)).

Сравните выводlist("a",6,7,8) против c("a",6,7,8).

1 голос
/ 23 октября 2019

Мы можем использовать add_row

library(tibble)
testdf <- add_row(testdf, !!!set_names(list('a', 6, 7, 8), names(testdf)))
testdf
#  a b c d
#1 b 2 3 4
#2 2 3 4 5
#3 a 6 7 8

Теперь сделайте pmax в числовых столбцах

testdf[2:3] / do.call(pmax, testdf[2:3])
#          b c
#1 0.6666667 1
#2 0.7500000 1
#3 0.8571429 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...