簡體   English   中英

R:按組,測試是否對於一個變量的每個值,該值存在於另一個變量中

[英]R: By group, test if for each value of one variable, that value exists in another variable

我有一個數據框結構類似於:

a <- c(1,1,1,2,2,2,3,3,3,3,4,4)
b <- c(1,2,3,1,2,3,1,2,3,4,1,2)
c <- c(NA, NA, 2, NA, 1, 1, NA, NA, 1, 1, NA, NA)

df <- data.frame(a,b,c)

其中ab唯一地標識觀察。 我想創建一個新變量d ,它指示b每個觀察值是否在c中至少存在一次,由a分組。 這樣d將是:

[1] 0 1 0 1 0 0 1 0 0 0 0 0

我可以編寫一個for循環來完成這個技巧,

attach(df)
for (i in unique(a)) {
  for (j in b[a == i]) {
    df$d[a == i & b == j] <- ifelse(j %in% c[a == i], 1, 0)
  }
}

但是肯定在R中必須有更清潔/更快的方法來實現相同的結果嗎?

使用data.table

library(data.table)
setDT(df) #convert df to a data.table without copying
# +() is code golf for as.integer
df[ , d := +(b %in% c), by = a]
#     a b  c d
#  1: 1 1 NA 0
#  2: 1 2 NA 1
#  3: 1 3  2 0
#  4: 2 1 NA 1
#  5: 2 2  1 0
#  6: 2 3  1 0
#  7: 3 1 NA 1
#  8: 3 2 NA 0
#  9: 3 3  1 0
# 10: 3 4  1 0
# 11: 4 1 NA 0
# 12: 4 2 NA 0

為那些說服添加dplyr版本。 歸功於@akrun的所有功勞。

library(dplyr)
df %>% group_by(a) %>% mutate(d = +(b %in% c))

對后代來說,還有一個base R版本(通過下面的@thelatemail)

df <- df[order(df$a, df$b), ]
df$d <- unlist(by(df, df$a, FUN = function(x) (x$b %in% x$c) + 0L ))

MichaelChirico的上述答案顯然運作良好且是正確的。 我很少使用data.table所以我不懂語法。 這是一種在沒有data.table的情況下獲得相同結果的方法。

invisible(lapply(unique(df$a), function(x) {
  df$d[df$a==x] <<- 0L + (df$b[df$a==x] %in% df$c[df$a==x])
}))

此代碼獲取a的所有唯一級別,然后使用您請求的邏輯修改該級別的data.frame。 << - 是必要的,因為否則將僅在apply的范圍內修改df而不是.GlobalEnv。 使用<< - 它找到定義了df的父環境並在那里設置df。

另外,請注意+“技巧”的略有不同的版本,其中前導0使讀者更清楚結果向量是一個整數,因為它必須以這種方式進行轉換才能使加法工作。 0之后的L表示0是整數而不是雙精度。 請注意,MichaelChirico用於此轉換的表示法給出了相同的結果(類整數列)。

暫無
暫無

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

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