20

国変数を因子として使用する次のデータフレーム(簡略化)があり、値変数に欠測値があります。

country value
AUT     NA
AUT     5
AUT     NA
AUT     NA
GER     NA
GER     NA
GER     7
GER     NA
GER     NA

以下は、上記のデータフレームを生成します。

data <- data.frame(country=c("AUT", "AUT", "AUT", "AUT", "GER", "GER", "GER", "GER", "GER"), value=c(NA, 5, NA, NA, NA, NA, 7, NA, NA))

ここで、最後の観測の繰り越し(LOCF)を使用して、各国のサブセットのNA値を置き換えたいと思います。zooパッケージのコマンドna.locfを知っています。次のデータフレームが表示されます。data <- na.locf(data)

country value
AUT     NA
AUT     5
AUT     5
AUT     5
GER     5
GER     5
GER     7
GER     7
GER     7

ただし、この関数は、国によって分割された個々のサブセットでのみ使用する必要があります。以下は私が必要とする出力です:

country value
AUT     NA
AUT     5
AUT     5
AUT     5
GER     NA
GER     NA
GER     7
GER     7
GER     7

私はそれを実装する簡単な方法を考えることができません。forループを始める前に、これを解決する方法について誰かが何か考えを持っているかどうか疑問に思いました。

どうもありがとう!!

4

8 に答える 8

15

ソリューションの最新バージョンはddply、パッケージを使用することdplyrです。

library(dplyr)
DF %>%
  group_by(county) %>% 
  mutate(value = na.locf(value, na.rm = F))      
于 2014-09-19T22:51:12.823 に答える
14

これがddply解決策です。これを試して

library(plyr)
ddply(DF, .(country), na.locf)
  country value
1     AUT  <NA>
2     AUT     5
3     AUT     5
4     AUT     5
5     GER  <NA>
6     GER  <NA>
7     GER     7
8     GER     7
9     GER     7

ddplyあなたがそれを見つけることができるヘルプ から編集

.variables:  variables to split data frame by, 
as quoted variables, a formula or character vector.

したがって、必要なものを取得するための別の選択肢は次のとおりです。

ddply(DF, "country", na.locf)
ddply(DF, ~country, na.locf)

.variablesで置き換えることは許可されていないことに注意してくださいDF$variable。これを行うとエラーが発生するのはそのためです。

DFあなたのdata.frameです

于 2012-11-29T01:07:15.110 に答える
8

locfを使用していなくても、整然とした方法は次のとおりです。

library(tidyverse)

data %>% 
    group_by(country) %>% 
    fill(value)

Source: local data frame [9 x 2]
Groups: country [2]

country value
(fctr) (dbl)
1     AUT    NA
2     AUT     5
3     AUT     5
4     AUT     5
5     GER    NA
6     GER    NA
7     GER     7
8     GER     7
9     GER     7
于 2017-01-13T02:54:53.637 に答える
6

data.framewithを分割し、サブセットbyで使用します。na.locf

do.call(rbind,by(data,data$country,na.locf))

行名を削除する場合:

do.call(rbind,unname(by(data,data$country,na.locf)))
于 2012-11-29T01:03:15.223 に答える
4

速度を考慮すると、このunstack/stackソリューションは私のシステムの他のソリューションよりも約4〜6倍高速ですが、コードの行が少し長くなります。

stack(lapply(unstack(data, value ~ country), na.locf, na.rm = FALSE))

別のアプローチは次のとおりです。

transform(data, value = ave(value, country, FUN = na.locf0))
于 2012-11-29T10:07:08.937 に答える
4

国ごとに分割する必要があります。次に、zoo :: na.locf()またはna.fillのいずれかを実行して、右側に入力します。na.fillの3コンポーネントarg構文を明示的に示す例を次に示します。

library(plyr)
library(zoo)

data <- data.frame(country=c("AUT", "AUT", "AUT", "AUT", "GER", "GER", "GER", "GER", "GER"), value=c(NA, 5, NA, NA, NA, NA, 7, NA, NA))

# The following is equivalent to na.locf
na.fill.right <- function(...) { na.fill(..., list(left=NA,interior=NA,right="extend")) }

ddply(data, .(country), na.fill.right)

  country value
1     AUT  <NA>
2     AUT     5
3     AUT     5
4     AUT     5
5     GER  <NA>
6     GER  <NA>
7     GER     7
8     GER     7
9     GER     7
于 2014-09-19T22:19:18.557 に答える
3

私はこの会話に少し遅れていますがdata.table、これが方法です。これは、より大きなデータセットの場合にはるかに高速になります。

library(zoo)
library(data.table)

# Convert to data table
setDT(data)

data[, value := na.locf(value, na.rm = FALSE), by = country]

data
   country  value
1:     AUT     NA
2:     AUT      5
3:     AUT      5
4:     AUT      5
5:     GER     NA
6:     GER     NA
7:     GER      7
8:     GER      7
9:     GER      7

# And if you want to convert "data" back to a data frame...
setDF(data)
于 2018-07-27T16:01:42.287 に答える
1

パッケージdplyrimputeTSの組み合わせがその仕事をすることができます。

library(dplyr)
library(imputeTS)
data %>% group_by(country) %>% 
mutate(value = na.locf(value, na.remaining="keep"))   

imputeTSのna.locf関数のna.remainingパラメーターを使用する、末尾のNAをどう処理するかを選択するオプションが追加されます。

これらはオプションです:

  • 「保持」-NAを使用してシリーズを返します
  • 「rm」-残りのNAを削除します
  • 「平均」-残りのNAを全体的な平均に置き換えます
  • "rev"-逆方向からnocb/locfを実行します

「平均」を選択すると、たとえば、特定の例のすべてのGERに対して7の結果が得られます。

于 2018-10-08T03:37:59.380 に答える