0

3列のdata.frameがあります。3 番目の列には、数字または文字タイプ「1:5」、「30:20」、「1:10」などがあります。これらの文字を含む値を 2 つに分割してから、それらの間で分割しようとしていますが、これで立ち往生しています:

    datos[,3]=gsub(":", " ", datos[,3])
    if (datos[,1]==TRUE)
    {
    s=datos[,3]
    chr.pos <- which(unlist(strsplit(s,NULL)) == " ") 
    chr.count <- length(chr.pos)
    one=as.numeric(substr(s,1,chr.pos-1))
    two=as.numeric(substr(s,chr.pos+1,nchar(as.character(s))))
    datos[,3]=round(two/one,5)
    }
4

2 に答える 2

3

コロンで区切られた 2 つの数値が常に存在することが確実な場合:は、次の操作を実行できます。

x <- c('1:5', '30:20', '1:10')
strsplit(x, ':')

lapply(strsplit(x, ':'), function(v) as.integer(v[1])/as.integer(v[2]))

次に、それを必要な場所に戻します。そのdata.frameの場合:

datos[,3] <- unlist(lapply(strsplit(x, ':'), function(v) as.integer(v[1])/as.integer(v[2]))
)

そのようなものを歩く:

strsplit渡した分割文字の両側にあるものを含むベクトルのリストを返します (私は を使用し:ました)。それが何をするか見てみましょう:

str(strsplit(x, ':'))

List of 3
 $ : chr [1:2] "1" "5"
 $ : chr [1:2] "30" "20"
 $ : chr [1:2] "1" "10"

lapply指定した関数をリストの各要素に適用してリストに作用します。の最初の値を 2 番目の値で割る関数を定義しvました。strsplitただし、文字列として出てくるので、数字に強制する必要がありました。

最後にlapply、リストも返します。これを自分の列に直接割り当てるdata.frameと、不愉快な驚きに直面することになります。代わりに、 を使用unlistしてリストをベクトルに変更し、それを列に割り当てdata.frameます。

また、コメントで言及されているように、 mnel はdata.tableR のパッケージであり、いくつかの素晴らしい機能を備えていますが、基本の R データ構造とは構文が大きく異なりますdata.frame

于 2012-12-17T23:25:11.863 に答える
1

これを試して。注: 行名のデフォルトの処理を抑制するために「col.names」を追加しました。

x=c("1", "2", "3", "2:3","4","5","3:2")
 datos <- data.frame(1:7, 1:7, x=x)
newframe <- cbind( datos[1:2], 
                 read.table(text= as.character(datos[[3]]), sep=":",
                            fill=TRUE, colClasses="numeric", 
                           col.names=c("V3", "V4")
                           )
                  )

> newframe
  X1.7 X1.7.1 V3 V4
1    1      1  1 NA
2    2      2  2 NA
3    3      3  3 NA
4    4      4  2  3
5    5      5  4 NA
6    6      6  5 NA
7    7      7  3  2
于 2012-12-17T23:53:36.350 に答える