1

x選択が各行に固有の場合、1 つの列の値 (たとえば、以下) を使用して、可能な列の中から値を選択するにはどうすればよいですか?

variableは、指定された行に対してxvariable ab、またはを選択する必要があるかどうかを決定します。c簡単な例を次に示します。実際のセルは、列名と行番号を連結したものではありません。

library(magrittr); requireNamespace("tibble"); requireNamespace("dplyr")

ds <- tibble::tibble(
  x   = c(  1 ,   1 ,   2 ,   3 ,   1 ),
  a   = c("a1", "a2", "a3", "a4", "a5"),
  b   = c("b1", "b2", "b3", "b4", "b5"),
  c   = c("c1", "c2", "c3", "c4", "c5")
)

必要な列の値は次のとおりです。

# ds$y_desired      <- c("a1", "a2", "b3", "c4", "a5")
# ds$column_desired <- c("a" , "a" , "b" , "c" , "a" )

もちろん、次の例では 1 列ではなく、5 列が生成されます。

ds[, ds$column_desired]

そして、以下はエラーを生成します: Error in mutate_impl(.data, dots) : basic_string::_M_replace_aux.

ds %>% 
  dplyr::rowwise() %>% 
  dplyr::mutate(
    y = .[[column_desired]]
  ) %>% 
  dplyr::ungroup()

実際のシナリオで選択肢が 2 つまたは 3 つしかない場合は、おそらくネストされた if を使用しますが、より多くの条件に対応するために一般化されたマッピング アプローチが必要です。

ds %>% 
  dplyr::mutate(
    y_if_chain = ifelse(x==1, a, ifelse(x==2, b, c))
  )

理想的には、このアプローチは、ルックアップ テーブル、または次のような他のメタデータ オブジェクトによって指示される可能性があります。

ds_lookup <- tibble::tribble(
  ~x,    ~desired_column,
  1L,                "a",
  2L,                "b",
  3L,                "c"
)

この列切り替えの質問は以前にもあったと思いますが、該当するものは見つかりませんでした。

私はtidyverseソリューションを好みます (私のチームが最も快適に使用できるのは b/c です) が、私はどのツールにもオープンです。applykimisc::vswitchを組み合わせて使用​​する方法がわかりませんでした。

4

4 に答える 4

1

これを試して:

ds$y_desired = apply(ds, 1, function(r) r[as.integer(r[1])+1])
于 2016-12-11T07:33:44.827 に答える
1

問題は、データが必要なものに対して間違った形式になっていることだと思います。まず、次のようにワイド形式からロング形式に変換しますtidyr::gather()

library("tidyr")
ds %>% 
  gather(y, col, a:c)

# A tibble: 15 × 3
#        x     y   col
#    <dbl> <chr> <chr>
# 1      1     a    a1
# 2      1     a    a2
# 3      2     a    a3
# 4      3     a    a4
# 5      1     a    a5
# 6      1     b    b1
# 7      1     b    b2
# 8      2     b    b3
# 9      3     b    b4
# 10     1     b    b5
# 11     1     c    c1
# 12     1     c    c2
# 13     2     c    c3
# 14     3     c    c4
# 15     1     c    c5

filterその後、タスクは、必要な条件 (例:x == 1, y == aなど)を実行するのと同じくらい簡単になります。

于 2016-12-11T11:09:06.193 に答える
0

@sirallenの回答から学んだ後、関数に関するHadleyの章を読み直しました。ここではswitch、Tidyverse スタイルの連鎖を含む、apply ファミリの他のメンバーと共に使用するソリューションを示します。

library(magrittr); requireNamespace("purrr"); requireNamespace("tibble"); requireNamespace("dplyr")

ds <- tibble::tibble(
  x   = c( 10 ,  10 ,  20 ,  30 ,  10 ),
  a   = c("a1", "a2", "a3", "a4", "a5"),
  b   = c("b1", "b2", "b3", "b4", "b5"),
  c   = c("c1", "c2", "c3", "c4", "c5")
)
determine_2 <- function( ss, a, b, c) {
  switch(
    as.character(ss),
    "10"    =   a,
    "20"    =   b,
    "30"    =   c
  )
}

# Each of these calls returns a vector.
unlist(Map(        determine_2, ds$x, ds$a, ds$b, ds$c))
mapply(            determine_2, ds$x, ds$a, ds$b, ds$c)
parallel::mcmapply(determine_2, ds$x, ds$a, ds$b, ds$c)                 # For Linux
unlist(purrr::pmap(list(        ds$x, ds$a, ds$b, ds$c), determine_2))

# Returns a dataset with the new variable.
ds %>%
  dplyr::mutate(
    y = unlist(purrr::pmap(list(x, a, b, c), determine_2))
  )
于 2016-12-12T19:35:18.323 に答える