从R中的最小值创建一个新变量

时间:2016-05-12 18:57:21

标签: r

数据包含四个字段:id, x1, x2, and x3

id <- c(1,2,3,4,5,6,7,8,9,10)
x1 <- c(2,4,5,3,6,4,3,6,7,7)
x2 <- c(0,1,2,6,7,6,0,8,2,2)
x3 <- c(5,3,4,5,8,3,4,2,5,6)

DF <- data.frame(id, x1,x2,x3)

在我提出这个问题之前,让我创建一个新的字段(minX),它是(x1,x2,x3)的最小值

DF$minX <- pmin(DF$x1, DF$x2, DF$x3)

我需要创建一个新字段y,其定义如下

if min(x1,x2,x3) = x1, then y = "x1"
if min(x1,x2,x3) = x2, then y = "x2"
if min(x1,x2,x3) = x3, then y = "x3"

注意:我们假设没有联系。

3 个答案:

答案 0 :(得分:4)

作为一个简单的解决方案,请执行:

which.min

函数apply返回最小值的索引。如果最小值不唯一,则返回第一个。既然你保证没有领带,这不是问题。

最后,您应该熟悉MARGIN = 1,对吗? FUN表示逐行应用函数MARGIN = 2,而FUN表示逐列应用for。这是一个有用的函数,可以避免在处理矩阵时需要apply循环。由于您的数据框只包含数字/整数值,因此它就像一个矩阵,因此我们可以使用<div ng-init="initObject = {initParam: 'initParamValue', anotherOne: 'value'}"></div>

答案 1 :(得分:1)

data.table解决方案:

# create variables
id <- c(1,2,3,4,5,6,7,8,9,10)
x1 <- c(2,4,5,3,6,4,3,6,7,7)
x2 <- c(0,1,2,6,7,6,0,8,2,2)
x3 <- c(5,3,4,5,8,3,4,2,5,6)
DF <- data.frame(id, x1,x2,x3)

# load package and set data table, calculating min
library(data.table)
setDT(DF)[, minx := apply(.SD, 1, min), .SDcols=c("x1", "x2", "x3")]

# Create variable with name of minimum
DF[, y := apply(.SD, 1, function(x) names(x)[which.min(x)]), .SDcols = c("x1", "x2", "x3")]

# call result
DF
##     id x1 x2 x3 minx  y
 1:  1  2  0  5    0 x2
 2:  2  4  1  3    1 x2
 3:  3  5  2  4    2 x2
 4:  4  3  6  5    3 x1
 5:  5  6  7  8    6 x1
 6:  6  4  6  3    3 x3
 7:  7  3  0  4    0 x2
 8:  8  6  8  2    2 x3
 9:  9  7  2  5    2 x2
10: 10  7  2  6    2 x2

可以直接调用最后一步,而无需计算minx。 请注意,data.table在大型数据集中特别快。

########编辑添加:DPLYR方法#########

为了完整性,这将是一个dplyr方法来产生相同的(最终)结果。在我从这个问题(see here)开始的问题中,这个解决方案被归功于@ eipi10:

DF %>% mutate(y = apply(.[,2:4], 1, function(x) names(x)[which.min(x)]))

当应用于1e6行数据帧(我的索尼笔记本电脑中大约17秒)时,此解决方案与原始答案中提供的data.table时间大致相同。

答案 2 :(得分:1)

以下是使用pminmax.col

的其他选项
library(data.table)
setDT(DF)[, c("minx", "y") := list(do.call(pmin, .SD), 
             names(.SD)[max.col(-1*.SD)]), .SDcols= x1:x3]
DF
#    id x1 x2 x3 minx  y
# 1:  1  2  0  5    0 x2
# 2:  2  4  1  3    1 x2
# 3:  3  5  2  4    2 x2
# 4:  4  3  6  5    3 x1
3 5:  5  6  7  8    6 x1
# 6:  6  4  6  3    3 x3
# 7:  7  3  0  4    0 x2
# 8:  8  6  8  2    2 x3
# 9:  9  7  2  5    2 x2
#10: 10  7  2  6    2 x2