[英]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.