You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在data.table中创建满足多列任一前缀匹配的标记变量

Fixing the "Any Column Starts With 'A'" Flag in data.table

Hey there! Let's sort out this flag variable you're trying to create. The problem with your current code is that you're calculating a single global maximum across all rows and columns in your .SD subset, which is why every row gets set to 1. Instead, we need to check per row if any of your target columns starts with "A".

First, Let's Recap Your Example Data

library(data.table)
DT = as.data.table(matrix(c(LETTERS[seq(1,9)], rep("A",3)), nrow=3, ncol=4))

This gives us:

V1 V2 V3 V4
1:  A  D  G  A
2:  B  E  H  A
3:  C  F  I  A

Solution 1: Using rowSums (Simple & Vectorized)

This method leverages vectorized operations to efficiently check each row:

DT[, letterA := as.integer(rowSums(sapply(.SD, grepl, pattern = "^A")) > 0), .SDcols = c("V1", "V2")]

How it works:

  1. sapply(.SD, grepl, "^A") generates a logical matrix where each column corresponds to one of your target columns (V1, V2), and each cell is TRUE if the value starts with "A".
  2. rowSums() counts how many TRUE values exist per row.
  3. Comparing to > 0 gives us TRUE if any column in the row meets the condition, and as.integer() converts that to 1/0.

Solution 2: Using Reduce (data.table-Friendly Logical OR)

This approach uses logical OR across columns per row, which is more explicit about the "any" condition:

DT[, letterA := as.integer(Reduce(`|`, lapply(.SD, grepl, pattern = "^A"))), .SDcols = c("V1", "V2")]

How it works:

  1. lapply(.SD, grepl, "^A") creates a list of logical vectors (one for each target column).
  2. Reduce(|, ...) combines these vectors with a logical OR operation—so each row gets TRUE if any of the columns had a match.
  3. as.integer() again converts the logical result to 1/0.

Why Your Original Code Failed

Your line:

DT[, letterA:= max(apply(.SD,2,grepl,pattern= "^A" )), .SDcols=c("V1","V2")]
  • apply(.SD, 2, grepl, "^A") returns a matrix of logical values (rows = your data rows, columns = V1/V2).
  • max() then takes the maximum of the entire matrix (which is TRUE/1 if any cell in those columns starts with "A"), resulting in a single value that gets assigned to all rows.

Result After Fixing

After running either solution, your DT will look like this:

V1 V2 V3 V4 letterA
1:  A  D  G  A       1
2:  B  E  H  A       0
3:  C  F  I  A       0

内容的提问来源于stack exchange,提问作者Noah Hammarlund

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:08:51