使用 Rbind 将元素添加到 R 中的数据框
Adding elements to a dataframe in R using Rbind
我正在使用以下方法从 df1 和 df2 创建一个名为 Alleles_df 的包含 3 列(char、char、int)的数据框:
Alleles_df <- data.frame('refsnp_id'=character(),'allele'=character(),
'chrom_start' = integer(),stringsAsFactors = F)
for (i in 1:nrow(df1)){
Alleles_df[i,] <- df1[(df1$col1[i]==df2$col1[i]),]
}
对于 i 的某些值,我收到以下错误:
Error in x[[jj]][iseq] <- vjj : replacement has length zero
这是因为列 df1 和 df2 与 i 的某些值不匹配。在这些情况下,如何使用 c("NA","NA",0)
绑定一行?非常感谢您的帮助!
df1 是来自名为 biomart 的在线服务器的数据。 df2 是我手动生成的。每个都有 3 列,包含染色体、等位基因、BaseLocation。
refsnp_id allele chrom_start
1 rs778598915 G/A/T 42693910
2 rs11541159 T/C 42693843
3 rs397514502 G/C 42693321
4 rs762949801 C/T 42693665
5 rs776304817 G/A/T 42693653
解释问题其实是在[]
的顺序。在 df1[i,][(df1$col1[i] == df2$col1[i]),]
中,如果 df1 的第 i 行没有匹配 col1 的行,您将得到 <0 rows> (or 0-length row.names)
。但是在 df1[(df1$col1[i]==df2$col1[i]),][i,]
如果 df1 中没有匹配 col1 的行,结果也是 0 行,但是第 i 行是 ,所以结果是一个长度为 3 的 NA 填充行的数据帧。
已编辑的解释 自从您编辑以来:问题是并非 df1 的每一行的 col1 都与 同一行的 col1 相匹配 在 df2.因此,为什么你得到 0 行。
在 ( df1[( df1$col1[i] == df2$col1[i] ), ][i, ]
) 之后添加 [i,]
仍然会给出一个长度为 3 (NAs) 的空行并且不会停止循环,但是您也可以不进行循环(见下文)。
如果你真的想要保持你的循环,你可以去掉像Alleles_df <- Alleles_df[-which( rowSums( is.na( Alleles_df ), na.rm = T ) == ncol( Alleles_df ) ), ]
这样的空行。
解决方法
但是,如果 df1 和 df2 具有相同的行数,并且所有可能匹配的等位基因始终位于 df1 和 df2 中的同一行,df1[df1$col1 == df2$col1, ]
会更快地获得相同的结果。
更好的解决方案
如果 df1 和 df2 没有相同的行数,或者如果你想获得所有具有匹配等位基因的行,即使它们不一定在你的数据框中的同一行(比如 'rs778598915' 在 df1 中的第 1 行可能在 df2 中的第 5 行),您可以找到匹配的行并将其 rbind 到 Alleles_df 而无需像这样的循环:
Alleles_df <- rbind(df[sapply(df$col1, function(x) match(x, df2$col1, nomatch = 0) ),])
我正在使用以下方法从 df1 和 df2 创建一个名为 Alleles_df 的包含 3 列(char、char、int)的数据框:
Alleles_df <- data.frame('refsnp_id'=character(),'allele'=character(),
'chrom_start' = integer(),stringsAsFactors = F)
for (i in 1:nrow(df1)){
Alleles_df[i,] <- df1[(df1$col1[i]==df2$col1[i]),]
}
对于 i 的某些值,我收到以下错误:
Error in x[[jj]][iseq] <- vjj : replacement has length zero
这是因为列 df1 和 df2 与 i 的某些值不匹配。在这些情况下,如何使用 c("NA","NA",0)
绑定一行?非常感谢您的帮助!
df1 是来自名为 biomart 的在线服务器的数据。 df2 是我手动生成的。每个都有 3 列,包含染色体、等位基因、BaseLocation。
refsnp_id allele chrom_start
1 rs778598915 G/A/T 42693910
2 rs11541159 T/C 42693843
3 rs397514502 G/C 42693321
4 rs762949801 C/T 42693665
5 rs776304817 G/A/T 42693653
解释问题其实是在[]
的顺序。在 df1[i,][(df1$col1[i] == df2$col1[i]),]
中,如果 df1 的第 i 行没有匹配 col1 的行,您将得到 <0 rows> (or 0-length row.names)
。但是在 df1[(df1$col1[i]==df2$col1[i]),][i,]
如果 df1 中没有匹配 col1 的行,结果也是 0 行,但是第 i 行是 ,所以结果是一个长度为 3 的 NA 填充行的数据帧。
已编辑的解释 自从您编辑以来:问题是并非 df1 的每一行的 col1 都与 同一行的 col1 相匹配 在 df2.因此,为什么你得到 0 行。
在 ( df1[( df1$col1[i] == df2$col1[i] ), ][i, ]
) 之后添加 [i,]
仍然会给出一个长度为 3 (NAs) 的空行并且不会停止循环,但是您也可以不进行循环(见下文)。
如果你真的想要保持你的循环,你可以去掉像Alleles_df <- Alleles_df[-which( rowSums( is.na( Alleles_df ), na.rm = T ) == ncol( Alleles_df ) ), ]
这样的空行。
解决方法
但是,如果 df1 和 df2 具有相同的行数,并且所有可能匹配的等位基因始终位于 df1 和 df2 中的同一行,df1[df1$col1 == df2$col1, ]
会更快地获得相同的结果。
更好的解决方案 如果 df1 和 df2 没有相同的行数,或者如果你想获得所有具有匹配等位基因的行,即使它们不一定在你的数据框中的同一行(比如 'rs778598915' 在 df1 中的第 1 行可能在 df2 中的第 5 行),您可以找到匹配的行并将其 rbind 到 Alleles_df 而无需像这样的循环:
Alleles_df <- rbind(df[sapply(df$col1, function(x) match(x, df2$col1, nomatch = 0) ),])