在R代码;在数据框(大小195 x 195)中,在一行中对应列最小值相关的行名和列名

时间:2016-12-31 07:50:59

标签: r

STOP_ID STP1    STP2    STP3    STP4    STP5    STP6
DEP1    10      518     497     131     16      131
DEP2    510     22      32      452     510     452
DEP3    487     27      45      439     487     430
DEP4    132     466    445      32      132     62
DEP5    43      518    487      131     55      483
DEP6    132     466    445      32      132     25

我在期待 rowname:DEP1,列名:STP1最小值:10

有人可以帮助我得到上述答案

3 个答案:

答案 0 :(得分:2)

我们可以使用max.col

的矢量化选项来完成此操作
j1 <- max.col(-df1[-1], "first")
res <- transform(df1, min_val = df1[-1][cbind(1:nrow(df1), j1)], 
                                            col_name = names(df1)[-1][i1])
res
#    STOP_ID STP1 STP2 STP3 STP4 STP5 STP6 min_val col_name
#1    DEP1   10  518  497  131   16  131      10     STP1
#2    DEP2  510   22   32  452  510  452      22     STP2
#3    DEP3  487   27   45  439  487  430      27     STP2
#4    DEP4  132  466  445   32  132   62      32     STP4
#5    DEP5   43  518  487  131   55  483      43     STP1
#6    DEP6  132  466  445   32  132   25      25     STP6

或使用data.table

library(data.table)
setDT(df1)[melt(setDT(df1), id.var = "STOP_ID", variable.name = "col_name",
         value.name = "min_val")[, .SD[which.min(min_val)], STOP_ID]
           , on = "STOP_ID"]
#    STOP_ID STP1 STP2 STP3 STP4 STP5 STP6 col_name min_val
#1:    DEP1   10  518  497  131   16  131     STP1      10
#2:    DEP2  510   22   32  452  510  452     STP2      22
#3:    DEP3  487   27   45  439  487  430     STP2      27
#4:    DEP4  132  466  445   32  132   62     STP4      32
#5:    DEP5   43  518  487  131   55  483     STP1      43
#6:    DEP6  132  466  445   32  132   25     STP6      25

如果我们只需要'STOP_ID','min_val'和'col_name'

melt(setDT(df1), id.var = "STOP_ID", variable.name = "col_name", 
            value.name = "min_val")[, .SD[which.min(min_val)], STOP_ID]
#    STOP_ID col_name min_val
#1:    DEP1     STP1      10
#2:    DEP2     STP2      22
#3:    DEP3     STP2      27
#4:    DEP4     STP4      32
#5:    DEP5     STP1      43
#6:    DEP6     STP6      25

答案 1 :(得分:1)

apply(df[2:7], 1, function(x) colnames(df[2:7])[which.min(x)])
# [1] "STP1" "STP2" "STP2" "STP4" "STP1" "STP6"
apply(df[2:7], 1, function(x) x[which.min(x)])
# [1] 10 22 27 32 43 25

如果您正在寻找的话,请将以上矢量添加到新列中。

x = apply(df[2:7], 1, function(x) colnames(df[2:7])[which.min(x)])
y = apply(df[2:7], 1, function(x) x[which.min(x)])
df$min_vale = y
df$col_name = x

# df
#  STOP_ID STP1 STP2 STP3 STP4 STP5 STP6 min_vale col_name
#1    DEP1   10  518  497  131   16  131       10     STP1
#2    DEP2  510   22   32  452  510  452       22     STP2
#3    DEP3  487   27   45  439  487  430       27     STP2
#4    DEP4  132  466  445   32  132   62       32     STP4
#5    DEP5   43  518  487  131   55  483       43     STP1
#6    DEP6  132  466  445   32  132   25       25     STP6

使用data.table

的另一种方法
library(data.table)
df1 = setDT(df)[, apply(.SD, 1, function(x) list(colnames(df[2:7])[which.min(x)], x[which.min(x)])),
            .SDcols = colnames(df)[2:7]]
colnames(df1) = df$STOP_ID
# df1
#      DEP1 DEP2 DEP3 DEP4    DEP5 DEP6
#1: STOP_ID STP1 STP1 STP3 STOP_ID STP5
#2:      10   22   27   32      43   25

答案 2 :(得分:1)

以下是使用dplyrtidyr

的另一种方法
library(dplyr)
library(tidyr)

df %>% 
  gather(c.names, value, STP1:STP6) %>%
  group_by(STOP_ID) %>% 
  filter(value == min(value)) %>%  
  arrange(value) %>% 
  rename(r.names = STOP_ID)

#Source: local data frame [6 x 3]
#Groups: r.names [6]

#  r.names c.names value
#   <fctr>   <chr> <int>
#1    DEP1    STP1    10
#2    DEP2    STP2    22
#3    DEP6    STP6    25
#4    DEP3    STP2    27
#5    DEP4    STP4    32
#6    DEP5    STP1    43