R: dplyr :: mutate, используя выражение, состоящее из комбинации переменных, переданных как строки - PullRequest
0 голосов
/ 25 мая 2018

Я хочу написать функцию, которая добавляет новую переменную во фрейм данных.Эта новая переменная состоит в объединении значений, соответствующих набору переменных, переданных в аргументе (как вектор строк).В базе R я бы написал что-то вроде:

addConcatFields<-function(data,listOfVar)
{
data$uniqueId=data[,listOfVar[1]]
for(elt in listOfVar[2:length(listOfVar)])
{
data$uniqueId=paste(data$uniqueId,data[,elt],sep='_')
}
return(data)
}

addConcatFields(iris,c('Petal.Width','Species'))

# gives:
      Sepal.Length Sepal.Width Petal.Length Petal.Width Species   uniqueId
1          5.1         3.5          1.4         0.2  setosa 0.2_setosa
2          4.9         3.0          1.4         0.2  setosa 0.2_setosa
...

Моя первоначальная цель состояла в том, чтобы сделать это с помощью dplyr :: mutate, и, несмотря на то, что я прочитал виньетку программирования http://127.0.0.1:31671/library/dplyr/doc/programming.html, Мне не удалось достичьмоя цель.Поскольку я хочу понять пропущенный момент, я хотел бы решить проблему с помощью mutate, и я был бы признателен за предложения.

Ответы [ 5 ]

0 голосов
/ 26 мая 2018

ОК, подумав об этом, вот еще одно решение.

Преобразование имен строк в номера столбцов с помощью функции соответствия.

Затем используйте номера столбцов, например, так (вместо числовогоvector в примере с результатами сопоставления):

df <- tbl_df(df[c(3, 4, 7, 1, 9, 8, 5, 2, 6, 10)])

Это также имеет то преимущество, что если сопоставление возвращает любые необнаруженные значения, вы можете прервать функцию с ошибкой.

0 голосов
/ 25 мая 2018

Лучший способ справиться с этим - использовать квази-цитату - эта статья действительно полезна для объяснения основных принципов.

https://dplyr.tidyverse.org/articles/programming.html

Вместо того, чтобы хранить имена столбцов в виде строк,лучший вариант - хранить их в виде строк в кавычках, таким образом:

varlist <- rlang::quos('Petal.Width', 'Species')

В этой строке содержится список из двух предложений - одно содержит столбец для Petal.Width и одно для вида.

Вы тогда хотите использовать !!!добавить список предложений в оператор dplyr (!!!, потому что вы объединяете более одной инструкции).

dplyr::select(iris, !!! varlist)

Должен дать желаемые результаты.

0 голосов
/ 25 мая 2018

Проверьте функцию unite в tidyr здесь .Он входит в tidyverse той же группы пакетов, в которую входит dplyr.

library(tidyr)
unite(iris,uniqueID,c(Petal.Width,Species))
#    Sepal.Length Sepal.Width Petal.Length       uniqueID
#1            5.1         3.5          1.4     0.2_setosa
#2            4.9         3.0          1.4     0.2_setosa
#3            4.7         3.2          1.3     0.2_setosa
#4            4.6         3.1          1.5     0.2_setosa

Если вы не хотите терять два сцепленных столбца, просто включите remove = F

unite(iris,uniqueID,c(Petal.Width,Species),remove = F)
#    Sepal.Length Sepal.Width Petal.Length       uniqueID Petal.Width    Species
#1            5.1         3.5          1.4     0.2_setosa         0.2     setosa
#2            4.9         3.0          1.4     0.2_setosa         0.2     setosa
#3            4.7         3.2          1.3     0.2_setosa         0.2     setosa
#4            4.6         3.1          1.5     0.2_setosa         0.2     setosa
0 голосов
/ 25 мая 2018

Чтобы добавить к другим ответам, так как вы сказали, что хотите сделать это, используя dplyr mutate.

Вот путь к этому в mutate, используя paste:

iris %>% mutate(uniqueId= paste(Petal.Width, Species, sep = '_'))
# gives the following result:
     Sepal.Length Sepal.Width Petal.Length Petal.Width Species uniqueId
 1          5.1         3.5          1.4         0.2 setosa  0.2_setosa
 2          4.9         3            1.4         0.2 setosa  0.2_setosa
 3          4.7         3.2          1.3         0.2 setosa  0.2_setosa
 4          4.6         3.1          1.5         0.2 setosa  0.2_setosa
 5          5           3.6          1.4         0.2 setosa  0.2_setosa
 6          5.4         3.9          1.7         0.4 setosa  0.4_setosa
 7          4.6         3.4          1.4         0.3 setosa  0.3_setosa
 8          5           3.4          1.5         0.2 setosa  0.2_setosa
 9          4.4         2.9          1.4         0.2 setosa  0.2_setosa
10          4.9         3.1          1.5         0.1 setosa  0.1_setosa
...

Если ваша функция - это пользовательская функция, вы можете векторизовать ее и затем использовать.Например, это приводит к тому же результату, что и выше:

concat_fields<-function(var1, var2) {
  return (paste(var1, var2, sep = '_'))
}
v_concat_fields <- Vectorize(concat_fields)
iris %>% mutate(v_concat_fields(Petal.Width, Species))

Функция, которая переходит в mutate, будет применена к столбцам фрейма данных, она имеет аргументы векторов типов, а не фреймы данных.

0 голосов
/ 25 мая 2018

Используя таблицу данных, я делаю что-то вроде этого

library(data.table)
iris <- data.table(iris)

iris[, uniqueId := do.call(function(...) paste(..., sep = "_"),.SD), .SDcols = c('Petal.Width','Species')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...