要替换的项目数不是数据框的替换长度的倍数

时间:2017-08-04 15:28:40

标签: r dataframe

我知道此主题已经存在很多帖子,但我仍然无法理解错误。我收到的错误是要替换的项目数不是替换长度的倍数。

当我在较小的练习数据框上运行我的代码时,它运行完美而没有任何错误。一旦我尝试在我的实际大数据帧上运行代码,我就会收到错误。这是因为我的数据框的大小,还是我完全忽略了这一点?

我已经看到其他人在运行for循环之前已经创建了一个临时矩阵或向量,我做了一次,但我需要做两次,因为我使用了两个for循环吗?我不明白为什么会出现这种情况,特别是如果它适用于较小的数据帧。

DF

Des.GeneSymbol <- c("A1BG", "A1BG", "A1BG", "A1BG", "A1BG", "A1BG-AS1", "A1BG-AS1", "A1BG-AS1", "A1BG-AS1", "admin.batch_number", "admin.file_uuid", "admin.month_of_dcc_upload", "admin.patient_withdrawal", "admin.project", "admin.year_of_dcc_upload", "patient.age_at_initial", "patient.anatomic_neoplasm", "patient.axillary_lymph_node") 
Des.Description <- c("CHR19-", "1", "1", "1", "Missense_Mutation", "CHR19+", "503538", "503538", "503538", "admin.file_uuid", "admin.month_of_dcc_upload", "admin.project", "admin.year_of_dcc_upload", "admin.patient_withdrawal", "patient.age_at_initial", "patient.anatomic_neoplasm", "admin.batch_number","patient.axillary_lymph_node") 
df <- data.frame(Des.GeneSymbol, Des.Description, row.names = 1:length(Des.GeneSymbol), stringsAsFactors = FALSE)
colnames(df) <- c("Des.GeneSymbol", "Des.Description")

创建了

    Des.GeneSymbol               Des.Description
1       A1BG                        CHR19-
2       A1BG                        1
3       A1BG                        1
4       A1BG                        1
5       A1BG                        Missense_Mutation
6       A1BG-AS1                    CHR19+
7       A1BG-AS1                    503538
8       A1BG-AS1                    503538
9       A1BG-AS1                    503538
10      admin.batch_number          admin.file_uuid
11      admin.file_uuid             admin.month_of_dcc_upload
12      admin.month_of_dcc_upload   admin.project
13      admin.patient_withdrawal    admin.year_of_dcc_upload
14      admin.project               admin.patient_withdrawl
15      admin.year_of_dcc_upload    patient.age_at_initial
16      patient.age_at_initial      patient.anatomic_neoplasm
17      patient.anatomic_neoplasm   admin.batch_number
18      patient.axillary_lymph_node patient.axillary_lymph_node

我编写的代码将Des.GeneSymbol中的值替换为Des.Description中的&#34; - &#34;。

remove_description <- df[, "Des.Description"]
count <- 1
for (cell in df[, "Des.GeneSymbol"]) {
  for(value in remove_description) {
    if (cell == value) {
      df[, "Des.GeneSymbol"][count] <- "-"
      break;
    }
  }
  count <- count + 1
}

期望的输出:

    Des.GeneSymbol       Des.Description
1       A1BG                CHR19-
2       A1BG                1
3       A1BG                1
4       A1BG                1
5       A1BG                Missense_Mutation
6       A1BG-AS1            CHR19+
7       A1BG-AS1            503538
8       A1BG-AS1            503538
9       A1BG-AS1            503538
10         -                admin.file_uuid
11         -                admin.month_of_dcc_upload
12         -                admin.project
13         -                admin.year_of_dcc_upload
14         -                admin.patient_withdrawl
15         -                patient.age_at_initial
16         -                patient.anatomic_neoplasm
17         -                admin.batch_number
18         -                patient.axillary_lymph_node

当我在实际数据帧上运行时,计数增量大约为120,000。错误不会在这个小数据帧上给出,只能在我较大的数据帧上给出。

有人可以解释为什么会发生这种情况吗?

编辑:将数据框与我提供的数据相匹配。我还将Des.Description中的值混合在一起,以更准确地显示所需内容。

1 个答案:

答案 0 :(得分:2)

编辑:OP已澄清他的生产数据比他的初始简化样本数据集更复杂。他已相应更新了问题和样本数据集。简化数据集的解决方案留在下面作为参考,但输出被删除,因为它不再匹配更新的,更实际的样本数据集。

简化案例的解决方案

很难理解双循环是如何工作的。因此,我建议使用基础R中的ifelse()“单行”:

df$Des.GeneSymbol <- ifelse(df$Des.GeneSymbol == df$Des.Description, "-", Des.GeneSymbol)
df

OP提供的示例表明替换是在每一行内。因此,ifelse()正在比较并逐行替换。

如果是大型数据框,切换到data.table可能更有效:

library(data.table)
setDT(df)[Des.GeneSymbol == Des.Description, Des.GeneSymbol := "-"][]

这里有两个好处:

  1. 只有ifelse()返回完整向量时,才会替换满足条件的那些行中的值。
  2. data.table更新到位,即不复制整个可能较大的对象。
  3. 然而,它仍然是一个逐行比较,而不是反映OP的生产数据。

    更新了解决方案

    OP已澄清匹配项目可能不在同一行。这就是为什么OP在他的代码中使用了双for循环的原因。

    通过澄清和更新的数据集,我们需要一种完全不同的方法来在data.frame中的其他位置查找匹配项。下面的代码使用自联接来查找其他行中的匹配项,并使用更新加入来替换匹配项。

    library(data.table)
    
    setDT(df)[df, on = c("Des.GeneSymbol==Des.Description"), Des.GeneSymbol := "-"][]
    
        Des.GeneSymbol             Des.Description
     1:           A1BG                      CHR19-
     2:           A1BG                           1
     3:           A1BG                           1
     4:           A1BG                           1
     5:           A1BG           Missense_Mutation
     6:       A1BG-AS1                      CHR19+
     7:       A1BG-AS1                      503538
     8:       A1BG-AS1                      503538
     9:       A1BG-AS1                      503538
    10:              -             admin.file_uuid
    11:              -   admin.month_of_dcc_upload
    12:              -               admin.project
    13:              -    admin.year_of_dcc_upload
    14:              -    admin.patient_withdrawal
    15:              -      patient.age_at_initial
    16:              -   patient.anatomic_neoplasm
    17:              -          admin.batch_number
    18:              - patient.axillary_lymph_node