簡體   English   中英

基於其他兩個列映射新數據框列的最快方法

[英]Fastest way to map a new data frame column based on two other columns

我有一個看起來像這樣的數據框:

id|value
01| 100
01| 101
01| 300 #edited for case I originally left out
02| 300
03| 100
03| 101
04| 100

並且我想添加一個新列,同時查看ID和分配給每個ID的值。

例如:如果一個id的值同時為100和101,我會將其添加到類別a。 如果id的值為300,我會將其添加到類別b。 如果一個id只有一個值(100或101,但不是兩個),則將其分配給類別c。

結果:

id|value|category
01| 100 |  a
01| 101 |  a
01| 300 |  b #edited for case I originally left out
02| 300 |  b
03| 100 |  a
03| 101 |  a
04| 100 |  c

我知道我可以遍歷它並分配類別,但是我的問題是是否有更快的矢量化方式?

data.table幾個選項

我們可以得到每個“ id”的元素數量為“ 100”,“ 101”,並將它們加在一起。 輸出將是0、1或2,分別對應於不存在,單個元素或兩者都不存在的情況。 可以將其轉換為factor並更改labels以使“ a”為“ 2”,“ b”為“ 0”,“ c”為“ 1”。

library(data.table)
setDT(df2)[, indx:=sum(unique(value)==100)+sum(unique(value)==101), 
  id][, category:=factor(indx, levels=c(2,0,1), labels=letters[1:3]) ][,
   indx:=NULL][]
#    id value category
#1:  1   100        a
#2:  1   101        a
#3:  2   300        b
#4:  3   100        a
#5:  3   101        a
#6:  4   100        c

或者我們可以創建一個命名向量('v1')並將其用作索引來映射按'id'分組的字符元素( toString(...) )。

v1 <- c('100, 101' = 'a', '300'='b', '100'= 'c', '101'='c')
setDT(df2)[, category := v1[toString(sort(unique(value)))], by=id][]
#    id value category
#1:  1   100        a
#2:  1   101        a
#3:  2   300        b
#4:  3   100        a
#5:  3   101        a
#6:  4   100        c

更新

根據新的數據集和新的條件,我們可以將第一個解決方案修改為

 setDT(df3)[, indx:= sum(unique(value)==100) + sum(unique(value)==101), id][, 
 category:= factor(indx, levels=c(2,0,1), labels=letters[1:3])][
 value==300, category:='b'][, indx:=NULL][]
 #    id value category
 #1:  1   100        a
 #2:  1   101        a
 #3:  1   300        b
 #4:  2   300        b
 #5:  3   100        a
 #6:  3   101        a
 #7:  4   100        c

或使用第二個選項

  v1 <- c('100, 101' = 'a', '100, 101, 300' = 'a', '300'='b',
            '100'= 'c', '101'='c')
  setDT(df3)[, category := v1[toString(sort(unique(value)))], 
                by=id][value==300, category := 'b'][]
  #   id value category
  #1:  1   100        a
  #2:  1   101        a
  #3:  1   300        b
  #4:  2   300        b
  #5:  3   100        a
  #6:  3   101        a
  #7:  4   100        c

數據

df2 <- structure(list(id = c(1L, 1L, 2L, 3L, 3L, 4L), value = c(100L, 
101L, 300L, 100L, 101L, 100L)), .Names = c("id", "value"), 
row.names = c(NA, -6L), class = "data.frame")

df3 <- structure(list(id = c(1L, 1L, 1L, 2L, 3L, 3L, 4L), 
value = c(100L, 101L, 300L, 300L, 100L, 101L, 100L)),
.Names = c("id", "value"), class = "data.frame",
 row.names = c(NA, -7L))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM