数据包含四个字段: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)的min。
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"注:我们假定没有联系。
发布于 2016-05-12 19:21:07
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方法。在我从这个问题开始的一个问题中,这个解决方案被认为是@eipi10 10,(see here)
DF %>% mutate(y = apply(.[,2:4], 1, function(x) names(x)[which.min(x)]))当应用于1e6行数据帧(在我的索尼笔记本上大约17秒)时,此解决方案与原始答案中提供的data.table解决方案相同。
发布于 2016-05-12 19:05:52
作为一个简单的解决方案,请:
VARS <- colnames(DF)[-1]
y <- VARS[apply(DF[, -1], MARGIN = 1, FUN = which.min)]
DF$y <- y函数which.min返回最小值的索引。如果最小值不是唯一的,则返回第一个。既然你保证没有平手,这就不是问题了。
最后,您应该熟悉apply,对吗?MARGIN = 1意味着按行应用函数,而MARGIN = 2则意味着应用FUN列。这是一个有用的函数,以避免在处理矩阵时需要一个for循环。因为您的数据帧只包含数值/整数值,所以它就像一个矩阵,因此我们可以使用apply。
发布于 2016-05-13 01:43:49
下面是使用pmin和max.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 x2https://stackoverflow.com/questions/37195322
复制相似问题