6

SASに代わる最良のRを最初に知っている人はいますか?または最後。演算子?何も見つかりませんでした。

SASは最初のものを持っています。そして最後。自動変数。特定の変数と同じ値を持つグループ内の最初と最後のレコードを識別します。したがって、次のデータセットでは、FIRST.modelとLAST.modelが定義されています。

Model,SaleID,First.Model,Last.Model
Explorer,1,1,0
Explorer,2,0,0
Explorer,3,0,0
Explorer,4,0,1
Civic,5,1,0
Civic,6,0,0
Civic,7,0,1
4

5 に答える 5

9

を探しているようですが!duplicatedfromLast引数はFALSEまたはTRUEです。

d <- datasets::Puromycin

d$state
# [1] treated   treated   treated   treated   treated   treated   treated  
# [8] treated   treated   treated   treated   treated   untreated untreated
#[15] untreated untreated untreated untreated untreated untreated untreated
#[22] untreated untreated
#Levels: treated untreated
!duplicated(d$state)
# [1]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#[13]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
!duplicated(d$state,fromLast=TRUE)
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
#[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

この関数にはいくつかの注意点とエッジケースの動作があり、ヘルプファイル(?duplicated)から確認できます。

于 2012-12-07T21:44:51.020 に答える
4

更新(最初に読む)

行インデックスのみに本当に関心がある場合は、おそらくいくつかの簡単な使用法splitとが役立つrangeでしょう。以下は、データセット内の行名に順番に番号が付けられていることを前提としていますが、おそらく適応も可能です。

irisFirstLast <- sapply(split(iris, iris$Species), 
                        function(x) range(as.numeric(rownames(x))))
irisFirstLast              ## Just the indices
#      setosa versicolor virginica
# [1,]      1         51       101
# [2,]     50        100       150
iris[irisFirstLast[1, ], ] ## `1` would represent "first"
#     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
# 1            5.1         3.5          1.4         0.2     setosa
# 51           7.0         3.2          4.7         1.4 versicolor
# 101          6.3         3.3          6.0         2.5  virginica
iris[irisFirstLast, ]      ## nothing would represent both first and last
#     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
# 1            5.1         3.5          1.4         0.2     setosa
# 50           5.0         3.3          1.4         0.2     setosa
# 51           7.0         3.2          4.7         1.4 versicolor
# 100          5.7         2.8          4.1         1.3 versicolor
# 101          6.3         3.3          6.0         2.5  virginica
# 150          5.9         3.0          5.1         1.8  virginica

d <- datasets::Puromycin   
dFirstLast <- sapply(split(d, d$state), 
                     function(x) range(as.numeric(rownames(x))))
dFirstLast
#      treated untreated
# [1,]       1        13
# [2,]      12        23
d[dFirstLast[2, ], ]       ## `2` would represent `last`
#    conc rate     state
# 12  1.1  200   treated
# 23  1.1  160 untreated

名前付き行を操作する場合、一般的なアプローチは同じですが、範囲を自分で指定する必要があります。一般的なパターンは次のとおりです。

datasetFirstLast <- sapply(split(dataset, dataset$groupingvariable), 
                           function(x) c(rownames(x)[1], 
                                         rownames(x)[length(rownames(x))]))

最初の答え(編集)

他の目的で行番号を必要とするのではなく、行を抽出することに関心がある場合は、を調べることもできますdata.table。ここではいくつかの例を示します。

library(data.table)
DT <- data.table(iris, key="Species")
DT[J(unique(Species)), mult = "first"]
#       Species Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1:     setosa          5.1         3.5          1.4         0.2
# 2: versicolor          7.0         3.2          4.7         1.4
# 3:  virginica          6.3         3.3          6.0         2.5
DT[J(unique(Species)), mult = "last"]
#       Species Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1:     setosa          5.0         3.3          1.4         0.2
# 2: versicolor          5.7         2.8          4.1         1.3
# 3:  virginica          5.9         3.0          5.1         1.8
DT[, .SD[c(1,.N)], by=Species]
#       Species Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1:     setosa          5.1         3.5          1.4         0.2
# 2:     setosa          5.0         3.3          1.4         0.2
# 3: versicolor          7.0         3.2          4.7         1.4
# 4: versicolor          5.7         2.8          4.1         1.3
# 5:  virginica          6.3         3.3          6.0         2.5
# 6:  virginica          5.9         3.0          5.1         1.8

この最後のアプローチは非常に便利です。たとえば、各グループの最初の3行と最後の3行が必要な場合は、次を使用できます。DT[, .SD[c(1:3, (.N-2):.N)], by=Species](参考のために:.Nグループごとのケースの数を表します。

その他の便利なアプローチは次のとおりです。

DT[, tail(.SD, 2), by = Species] ## last two rows of each group
DT[, head(.SD, 4), by = Species] ## first four rows of each group
于 2012-12-09T12:05:16.600 に答える
4

n=1オプションをbyと組み合わせたheadandtail関数は、良い方法です。 SASおよびSPssユーザーの場合はRを参照**(Robert Muenchen)対象の変数、つまり最後の変数を使用してデータフレームを作成します。

dfby<- data.frame(df$var1, df$var2)
mylastList<-by(df,dfby,tail, n=1)
#turn into a dataframe
mylastDF<-do.call(rbind,mylastList)
于 2012-12-12T13:05:58.420 に答える
3

これがdplyrソリューションです:

# input
dataset <- structure(list(Model = structure(c(2L, 2L, 2L, 2L, 1L, 1L, 1L
), .Label = c("Civic", "Explorer"), class = "factor"), SaleID = 1:7), .Names = c("Model", 
"SaleID"), class = "data.frame", row.names = c(NA, -7L))


# code 
library(dplyr)

dataset %>% 

  group_by(Model) %>%

  mutate(
          "First"        = row_number() == min( row_number() ),
          "Last"         = row_number() == max( row_number() )
  )

# output:

     Model SaleID First  Last
    <fctr>  <int> <lgl> <lgl>
1 Explorer      1  TRUE FALSE
2 Explorer      2 FALSE FALSE
3 Explorer      3 FALSE FALSE
4 Explorer      4 FALSE  TRUE
5    Civic      5  TRUE FALSE
6    Civic      6 FALSE FALSE
7    Civic      7 FALSE  TRUE

PS:dplyrがインストールされていない場合は、次のコマンドを実行します。

install.packages("dplyr")
于 2017-06-12T13:19:04.623 に答える
1

以下の関数は、@JoeのFirst/Lastの説明に基づいています。
この関数は、ベクトルのリストを返します。

各リストエントリは、データフレームの列(つまり、データセットの機能または変数)に対応します。
次に、特定のリストエントリ内に、すべての観測カテゴリの最初(または最後)の要素に関連するインデックスがあります。

使用例:

# Pass in your data frame, and indicate whether or not you want to find Last or find First. 
# Assign to the appropriate variable
first <- findFirstLast(myDF)
last  <- findFirstLast(myDF, findFirst=FALSE)

使用例data(iris)

data(iris)
first <- findFirstLast(iris)
last  <- findFirstLast(iris, findFirst=FALSE)

各種のどの観察:

 first$Species
 #    setosa versicolor  virginica 
 #        1         51        101 

 last$Species
 #    setosa versicolor  virginica 
 #        50        100        150 

sepciesの最初の観測ごとに行全体を取得します

iris[first$Species, ]
#      Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#  1            5.1         3.5          1.4         0.2     setosa
#  51           7.0         3.2          4.7         1.4 versicolor
#  101          6.3         3.3          6.0         2.5  virginica




関数findFirstLast()のコード:

  findFirstLast <- function(myDF, findFirst=TRUE) {
  # myDF should be a data frame or matrix 

    # By default, this function finds the first occurence of each unique value in a column
    # If instead we want to find last, set findFirst to FALSE.  This will give `maxOrMin` a value of -1
    #    finding the min of the negative indecies is the same as finding the max of the positive indecies. 
    maxOrMin <- ifelse(findFirst, 1, -1) 


    # For each column in myDF, make a list of all unique values (`levs`) and iterate over that list, 
    #   finding the min (or max) of all the indicies of where that given value appears within the column  
    apply(myDF, 2, function(colm) {
        levs <- unique(colm)
        sapply(levs, function(lev) {
          inds <- which(colm==lev)
          ifelse(length(inds)==0, NA, maxOrMin*min(inds*maxOrMin) ) 
        })   
      })
  }
于 2012-12-07T21:28:20.520 に答える