21

手始めに:私は今までにこの問題について何時間も検索しました-それで答えが些細なものであるならば、私を許してください...

私がやりたいのは、data.frameから行(101番)を削除することです。これにはテストデータが含まれているため、私の分析には表示されません。私の問題は次のとおりです。data.frameからサブセット化するたびに、属性(特にコメント)が失われます。

str(x)
# x has comments for each variable
x <- x[1:100,]
str(x)
# now x has lost all comments

サブセット化によってすべての属性が削除されることは十分に文書化されています-これまでのところ、それは完全に明らかです。マニュアル(例:http ://stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.data.frame.html )は、属性を保持する方法を提案しています。

## keeping special attributes: use a class with a
## "as.data.frame" and "[" method:


as.data.frame.avector <- as.data.frame.vector

`[.avector` <- function(x,i,...) {
  r <- NextMethod("[")
  mostattributes(r) <- attributes(x)
  r
}

d <- data.frame(i= 0:7, f= gl(2,4),
                u= structure(11:18, unit = "kg", class="avector"))
str(d[2:4, -1]) # 'u' keeps its "unit"

ここで正確に何が起こっているのかを理解するために、私はまだRにまだ詳しくありません。ただし、これらの行(最後の3行を除く)を実行するだけでは、サブセット化の動作は変わりません。適切なベクトル(100倍のTRUE + 1 FALSE)でコマンドsubset()を使用すると、同じ結果が得られます。また、属性を変数に格納し、サブセットの後でそれを復元するだけでも機能しません。

# Does not work...
tmp <- attributes(x)
x <- x[1:100,]
attributes(x) <- tmp

もちろん、すべてのコメントをベクター(var => comment)に書き込み、サブセット化して、ループを使用して書き戻すことはできますが、それは十分に根拠のある解決策ではないようです。そして、将来の分析で他の関連する属性を持つデータセットに遭遇することは間違いありません。

だから、これはスタックオーバーフロー、グーグル、そして頭脳の力での私の努力が行き詰まったところです。誰かがヒントを手伝ってくれたらとてもありがたいです。ありがとう!

4

4 に答える 4

12

私があなたを正しく理解している場合、あなたはdata.frameにいくつかのデータを持っており、data.frameの列にはそれらに関連付けられたコメントがあります。おそらく次のようなものですか?

set.seed(1)

mydf<-data.frame(aa=rpois(100,4),bb=sample(LETTERS[1:5],
  100,replace=TRUE))

comment(mydf$aa)<-"Don't drop me!"
comment(mydf$bb)<-"Me either!"

だからこれはあなたに次のようなものを与えるでしょう

> str(mydf)
'data.frame':   100 obs. of  2 variables:
 $ aa: atomic  3 3 4 7 2 7 7 5 5 1 ...
  ..- attr(*, "comment")= chr "Don't drop me!"
 $ bb: Factor w/ 5 levels "A","B","C","D",..: 4 2 2 5 4 2 1 3 5 3 ...
  ..- attr(*, "comment")= chr "Me either!"

そして、これをサブセット化すると、コメントが削除されます。

> str(mydf[1:2,]) # comment dropped.
'data.frame':   2 obs. of  2 variables:
 $ aa: num  3 3
 $ bb: Factor w/ 5 levels "A","B","C","D",..: 4 2

コメントを保持するには、上記のように(ドキュメントから)関数を定義して[.avectorから、data.frameの各列に適切なクラス属性を追加します(編集:の因子レベルを維持するには、のクラスにbb追加します。 )::"factor"bb

mydf$aa<-structure(mydf$aa, class="avector")
mydf$bb<-structure(mydf$bb, class=c("avector","factor"))

コメントが保持されるように:

> str(mydf[1:2,])
'data.frame':   2 obs. of  2 variables:
 $ aa:Class 'avector'  atomic [1:2] 3 3
  .. ..- attr(*, "comment")= chr "Don't drop me!"
 $ bb: Factor w/ 5 levels "A","B","C","D",..: 4 2
  ..- attr(*, "comment")= chr "Me either!"

編集:

data.frameに保持したい属性を持つ列が多数ある場合は、次を使用できますlapply(元の列クラスを含めるように編集):

mydf2 <- data.frame( lapply( mydf, function(x) {
  structure( x, class = c("avector", class(x) ) )
} ) )

ただし、これにより、data.frame自体に関連付けられたコメント(などcomment(mydf)<-"I'm a data.frame")が削除されるため、コメントがある場合は、それらを新しいdata.frameに割り当てます。

comment(mydf2)<-comment(mydf)

そして、あなたは

> str(mydf2[1:2,])
'data.frame':   2 obs. of  2 variables:
 $ aa:Classes 'avector', 'numeric'  atomic [1:2] 3 3
  .. ..- attr(*, "comment")= chr "Don't drop me!"
 $ bb: Factor w/ 5 levels "A","B","C","D",..: 4 2
  ..- attr(*, "comment")= chr "Me either!"
 - attr(*, "comment")= chr "I'm a data.frame"
于 2012-05-01T21:29:13.067 に答える
5

ベンバーンズの説明に基づいた「オールイン」ソリューションをお探しの方へ:こちらです。

(これがあなたのために働いているなら、BenBarnesからの投稿にあなたの「アップ」を与えてください)

# Define the avector-subselection method (from the manual)
as.data.frame.avector <- as.data.frame.vector
`[.avector` <- function(x,i,...) {
  r <- NextMethod("[")
  mostattributes(r) <- attributes(x)
  r
}

# Assign each column in the data.frame the (additional) class avector
# Note that this will "lose" the data.frame's attributes, therefore write to a copy
df2 <- data.frame(
  lapply(df, function(x) {
    structure( x, class = c("avector", class(x) ) )
  } )
)

# Finally copy the attribute for the original data.frame if necessary
mostattributes(df2) <- attributes(df)

# Now subselects work without losing attributes :)
df2 <- df2[1:100,]
str(df2)

良い点:クラスをすべてのdata.frameの要素に一度アタッチすると、副選択が属性を煩わせることはありません。

わかりました-Rで最も単純な操作を行うのがどれほど複雑であるかに驚かされることがあります。しかし、SPSSでケースにマークを付けて削除しただけでは、「クラス」機能については確かに学びませんでした;)

于 2012-05-02T19:02:36.437 に答える
3

これはstickyパッケージによって解決されます。(完全開示:私はパッケージの作成者です。)sticky()をベクトルに適用すると、サブセット操作によって属性が保持されます。例えば:

> df <- data.frame( 
+   sticky   = sticky( structure(1:5, comment="sticky attribute") ),
+   nonstick = structure( letters[1:5], comment="non-sticky attribute" )
+ )
> 
> comment(df[1:3, "nonstick"])
NULL
> comment(df[1:3, "sticky"])
[1] "sticky attribute"

これは、だけでなく、すべての属性に対して機能しますcomment

詳細については、stickyパッケージを参照してください。

于 2016-10-19T13:47:47.173 に答える
0

データフレームをサブセット化する(列を削除する)ときに、属性データ(特に変数ラベル)を保持する方法を理解するために何時間も費やしました。答えはとても単純で、信じられませんでした。Hmiscパッケージの関数spss.getを使用するだけで、サブセット化の方法に関係なく、変数ラベルが保持されます。

于 2018-04-20T21:11:53.027 に答える