根据ID在data.frame中寻址单元格

问题描述 投票:2回答:1

我在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

有办法吗?

r dataframe
1个回答
0
投票

这个问题似乎很简单,但答案中有不同的方面需要考虑。

OP已询问如何替换与给定ID值匹配的行中某列的值。

Data types

首先,您必须考虑用于替换的数据类型。因此,如果A要包含numeric类型的数据和类型为character的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将避免因错误的因子水平而导致的错误。

Base R

如上所述,by dshkolwhich(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

Using 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

Using a keyed data.table

在data.table上设置一个键将进一步加快搜索特定的ID,代码将变得更加简洁:

setkey(dt, ID)
dt[.(8), A := 0.7][]

输出与上面显示的相同。

Replacing multiple values at once using a lookup table

如果要在一列中替换许多值,将它们存储在查找表中并在连接操作的更新中使用它可能更有效:

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
© www.soinside.com 2019 - 2024. All rights reserved.