R语言报错:non-numeric argument to binary operator 解决方案咨询
解决R代码中
non-numeric argument to binary operator错误 问题描述
运行代码时触发错误:Error in coefficients * c(x["price"], as.numeric(x["taste"] == "Sour" | : non-numeric argument to binary operator,尝试使用x$price但因x是原子向量无法生效。
原代码如下:
# Set the seed for reproducibility set.seed(123) # Create a design matrix with different levels for each factor price <- rep(c(1, 2, 3), each = 4) taste <- rep(c("Sweet", "Sour", "Salty", "Spicy"), times = 3) texture <- rep(c("Crunchy", "Smooth"), each = 6) design_matrix <- data.frame(price, taste, texture) # Generate random utility coefficients for each factor coefficients <- c(-0.5, -0.3, 0.8) # Calculate the utility of each food option for each combination of factors utility <- apply(design_matrix, 1, function(x) { sushi_utility <- sum(coefficients * c(x["price"], as.numeric(x["taste"] == "Sour" | x["taste"] == "Salty"), as.numeric(x["texture"] == "Smooth"))) pizza_utility <- sum(coefficients * c(x["price"], as.numeric(x["taste"] == "Sweet" | x["taste"] == "Spicy"), as.numeric(x["texture"] == "Crunchy"))) burger_utility <- sum(coefficients * c(x["price"], as.numeric(x["taste"] == "Salty" | x["taste"] == "Spicy"), as.numeric(x["texture"] == "Crunchy"))) # Calculate the probability of choosing each food option probabilities <- exp(c(sushi_utility, pizza_utility, burger_utility)) probabilities <- probabilities / sum(probabilities) # Simulate the choice of food option based on the probabilities food <- sample(c("Sushi", "Pizza", "Burger"), size = 1, prob = probabilities) # Return a data frame with the factors and the chosen food option data.frame(price = x["price"], taste = x["taste"], texture = x["texture"], food = food) }) # Print the first few rows of the simulated dataset head(utility)
错误原因
使用apply(design_matrix, 1, function(x))时,每一行的x会被转换为原子向量。由于原数据框包含字符型列(taste),整个向量的类型会被统一为字符型,导致x["price"]返回字符值,无法与数值型的coefficients进行乘法运算。
解决办法
方法1:在apply函数内转换向量类型
将原子向量x转换为数据框,保留各列的原始类型,避免类型统一:
utility <- apply(design_matrix, 1, function(x) { # 将原子向量转为数据框,保留原列类型 x_df <- as.data.frame(t(x), stringsAsFactors = FALSE) sushi_utility <- sum(coefficients * c(x_df$price, as.numeric(x_df$taste == "Sour" | x_df$taste == "Salty"), as.numeric(x_df$texture == "Smooth"))) pizza_utility <- sum(coefficients * c(x_df$price, as.numeric(x_df$taste == "Sweet" | x_df$taste == "Spicy"), as.numeric(x_df$texture == "Crunchy"))) burger_utility <- sum(coefficients * c(x_df$price, as.numeric(x_df$taste == "Salty" | x_df$taste == "Spicy"), as.numeric(x_df$texture == "Crunchy"))) probabilities <- exp(c(sushi_utility, pizza_utility, burger_utility)) probabilities <- probabilities / sum(probabilities) food <- sample(c("Sushi", "Pizza", "Burger"), size = 1, prob = probabilities) data.frame(price = x_df$price, taste = x_df$taste, texture = x_df$texture, food = food) })
或者更简洁地直接将x["price"]转为数值型(需每次提取时都转换):
sushi_utility <- sum(coefficients * c(as.numeric(x["price"]), as.numeric(x["taste"] == "Sour" | x["taste"] == "Salty"), as.numeric(x["texture"] == "Smooth")))
方法2:使用dplyr::rowwise()替代apply(推荐)
用dplyr的行处理方式,无需担心类型转换问题,代码更易读维护:
library(dplyr) set.seed(123) price <- rep(c(1, 2, 3), each = 4) taste <- rep(c("Sweet", "Sour", "Salty", "Spicy"), times = 3) texture <- rep(c("Crunchy", "Smooth"), each = 6) design_matrix <- data.frame(price, taste, texture) coefficients <- c(-0.5, -0.3, 0.8) utility <- design_matrix %>% rowwise() %>% mutate( # 计算各食物效用 sushi_utility = sum(coefficients * c(price, as.numeric(taste %in% c("Sour", "Salty")), as.numeric(texture == "Smooth"))), pizza_utility = sum(coefficients * c(price, as.numeric(taste %in% c("Sweet", "Spicy")), as.numeric(texture == "Crunchy"))), burger_utility = sum(coefficients * c(price, as.numeric(taste %in% c("Salty", "Spicy")), as.numeric(texture == "Crunchy"))), # 计算选择概率 total_prob = exp(sushi_utility) + exp(pizza_utility) + exp(burger_utility), prob_sushi = exp(sushi_utility) / total_prob, prob_pizza = exp(pizza_utility) / total_prob, prob_burger = exp(burger_utility) / total_prob, # 模拟选择 food = sample(c("Sushi", "Pizza", "Burger"), size = 1, prob = c(prob_sushi, prob_pizza, prob_burger)) ) %>% select(price, taste, texture, food) head(utility)
内容的提问来源于stack exchange,提问作者Ruggiero Rippo
相关产品推荐
相关产品推荐

