我在R中有一个data.frame。看起来像这样(但要大得多):
df <- data.frame(A = rep(NULL, 5),
B = rep(NULL, 5),
ID = c(3,6,8,9,27))
> df
A B ID
1 NULL NULL 3
2 NULL NULL 6
3 NULL NULL 8
4 NULL NULL 9
5 NULL NULL 27
为了将相应的值写入每个单元格,我需要通过列名和ID值(第3列)精确地对每个单元格进行处理。因此,在以下示例中,X将由 column = A 和 ID = 8 处理。 (而不是 column = A 和 Row = 3 )
> df
A B ID
1 NULL NULL 3
2 NULL NULL 6
3 X NULL 8
4 NULL NULL 9
5 NULL NULL 27
有办法吗?
答案 0 :(得分:0)
这个问题似乎相当简单,但答案中有不同的方面需要考虑。
OP已询问如何替换与给定ID
值匹配的行中某列的值。
首先,您必须考虑用于替换的数据类型。因此,如果A
要包含数字类型的数据和类型为字符的B
,则可以通过
df <- data.frame(A = NA_real_,
B = NA_character_,
ID = c(3,6,8,9,27),
stringsAsFactors = FALSE)
df
A B ID 1 NA <NA> 3 2 NA <NA> 6 3 NA <NA> 8 4 NA <NA> 9 5 NA <NA> 27
str(df)
'data.frame': 5 obs. of 3 variables: $ A : num NA NA NA NA NA $ B : chr NA NA NA NA ... $ ID: num 3 6 8 9 27
这样可以避免代价高昂的类型转换。参数stringsAsFactors = FALSE
将避免因错误的因子水平而导致的错误。
如上所述by dshkol,which(df$ID==8)
返回行号。所以,一个完整的答案是:
df[which(df$ID == 8), "A"] <- 0.7
df
A B ID 1 NA <NA> 3 2 NA <NA> 6 3 0.7 <NA> 8 4 NA <NA> 9 5 NA <NA> 27
data.table
OP已经提到生产数据框更大。如果对大型数据对象有许多替换操作,则可能值得考虑使用data.table
,因为这些只在受影响的行中就地完成,即不复制整个列。这将节省时间和记忆。
此外,语法更简洁。
library(data.table)
dt <- as.data.table(df) # creating a copy of df for illustration
# replacement in place in rows given by row number
dt[which(ID == 8), A := 0.7][]
# replacement in place in rows given by condition
dt[ID == 8, A := 0.7][]
A B ID 1: NA NA 3 2: NA NA 6 3: 0.7 NA 8 4: NA NA 9 5: NA NA 27
data.table
在data.table上设置密钥将进一步加快搜索特定ID
的速度,代码将变得更加简洁:
setkey(dt, ID)
dt[.(8), A := 0.7][]
输出与上面显示的相同。
如果要在一列中替换许多值,将它们存储在查找表中并在更新连接操作中使用它可能更有效:
lookupA <- data.table(ID = c(8, 3),
new = c(0.7, 1.2))
lookupA
ID new 1: 8 0.7 2: 3 1.2
dt[lookupA, on = "ID", A := new][]
A B ID 1: 1.2 NA 3 2: NA NA 6 3: 0.7 NA 8 4: NA NA 9 5: NA NA 27