[英]R: losing column names when adding rows to an empty data frame
我剛從 R 開始,遇到了一個奇怪的行為:在空數據框中插入第一行時,原始列名會丟失。
例子:
a<-data.frame(one = numeric(0), two = numeric(0))
a
#[1] one two
#<0 rows> (or 0-length row.names)
names(a)
#[1] "one" "two"
a<-rbind(a, c(5,6))
a
# X5 X6
#1 5 6
names(a)
#[1] "X5" "X6"
rbind
幫助頁面指定:
對於'cbind'('rbind'),除非結果為零行(列),否則忽略零長度(包括'NULL')的向量,以實現S兼容性。 (零范圍矩陣不會出現在S3中,並且在R中不會被忽略)
所以,事實上,在你的rbind
指令中忽略了a
。 看起來並沒有完全忽略,因為它是一個數據框, rbind
函數被稱為rbind.data.frame
:
rbind.data.frame(c(5,6))
# X5 X6
#1 5 6
也許插入行的一種方法可能是:
a[nrow(a)+1,] <- c(5,6)
a
# one two
#1 5 6
但根據您的代碼,可能有更好的方法。
幾乎屈服於這個問題。
1)創建數據框,其中stringsAsFactor
設置為FALSE
或者直接進入下一個問題
2)不要使用rbind
- 不知道為什么它在搞亂列名。 簡單地這樣做:
df[nrow(df)+1,] <- c("d","gsgsgd",4)
df <- data.frame(a = character(0), b=character(0), c=numeric(0))
df[nrow(df)+1,] <- c("d","gsgsgd",4)
#Warnmeldungen:
#1: In `[<-.factor`(`*tmp*`, iseq, value = "d") :
# invalid factor level, NAs generated
#2: In `[<-.factor`(`*tmp*`, iseq, value = "gsgsgd") :
# invalid factor level, NAs generated
df <- data.frame(a = character(0), b=character(0), c=numeric(0), stringsAsFactors=F)
df[nrow(df)+1,] <- c("d","gsgsgd",4)
df
# a b c
#1 d gsgsgd 4
解決方法是:
a <- rbind(a, data.frame(one = 5, two = 6))
?rbind
聲明合並對象需要匹配名稱:
然后它從第一個數據框中獲取列的類,並按名稱(而不是按位置)匹配列
FWIW,一種替代設計可能會讓您的函數為兩列構建向量,而不是重新綁定到數據框:
ones <- c()
twos <- c()
修改函數中的向量:
ones <- append(ones, 5)
twos <- append(twos, 6)
根據需要重復,然后一次創建data.frame:
a <- data.frame(one=ones, two=twos)
一般來說,使用最少量的重新鍵入列名稱的方法是以下方法。 此方法不需要黑客攻擊NA或0。
rs <- data.frame(i=numeric(), square=numeric(), cube=numeric())
for (i in 1:4) {
calc <- c(i, i^2, i^3)
# append calc to rs
names(calc) <- names(rs)
rs <- rbind(rs, as.list(calc))
}
rs將具有正確的名稱
> rs
i square cube
1 1 1 1
2 2 4 8
3 3 9 27
4 4 16 64
>
另一種更干凈的方法是使用data.table:
> df <- data.frame(a=numeric(0), b=numeric(0))
> rbind(df, list(1,2)) # column names are messed up
> X1 X2
> 1 1 2
> df <- data.table(a=numeric(0), b=numeric(0))
> rbind(df, list(1,2)) # column names are preserved
a b
1: 1 2
請注意,data.table也是data.frame。
> class(df)
"data.table" "data.frame"
你可以這樣做:
給初始數據框一行
df=data.frame(matrix(nrow=1,ncol=length(newrow))
添加新行並取出NAS
newdf=na.omit(rbind(newrow,df))
但要注意你的新手沒有NA,否則它也會被刪除。
干杯阿古斯
我使用以下解決方案向空數據框添加一行:
d_dataset <-
data.frame(
variable = character(),
before = numeric(),
after = numeric(),
stringsAsFactors = FALSE)
d_dataset <-
rbind(
d_dataset,
data.frame(
variable = "test",
before = 9,
after = 12,
stringsAsFactors = FALSE))
print(d_dataset)
variable before after
1 test 9 12
HTH。
親切的問候
喬治·
研究這個古老的 R 煩惱將我帶到了這個頁面。 我想為 Georg 的出色答案( https:\/\/stackoverflow.com\/a\/41609844\/2757825<\/a> )添加更多解釋,這不僅解決了 OP 提出的問題(丟失字段名稱),而且還防止了不必要的轉換所有領域的因素。 對我來說,這兩個問題是一起出現的。 我想要一個不涉及編寫額外代碼但保留兩個不同操作的基本 R 解決方案:定義數據框,附加行 - 這是 Georg 的答案提供的。
下面的前兩個示例說明了問題,第三個和第四個示例顯示了 Georg 的解決方案。
而不是使用numeric(0)
構造data.frame我使用as.numeric(0)
。
a<-data.frame(one=as.numeric(0), two=as.numeric(0))
這會創建一個額外的初始行
a
# one two
#1 0 0
綁定其他行
a<-rbind(a,c(5,6))
a
# one two
#1 0 0
#2 5 6
然后使用負索引刪除第一行(偽造)行
a<-a[-1,]
a
# one two
#2 5 6
注意:它弄亂了索引(最左邊)。 我還沒弄明白如何防止這種情況(其他人?),但大多數時候它可能並不重要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.