作為一個更大專案的一部分,我試圖基于用戶指定變數的互動在一個名為“unique_id”的 data.frame 中創建一個新列。在這個用例中,每個用戶所需的變數數量和名稱會有很大差異,因此這種靈活性很重要。一些 data.frames,比如我在我的例子中制作的玩具,甚至會帶有一個“唯一的 id”變數,但這種情況非常罕見。我包括在我的例子中,以明確我想要的輸出是什么。
考慮這個玩具 data.frame:
mini_df <- data.frame(
lat = c(41.23,37.37,41.23,39.01,32.00),
lon = c(-120.79,-120.68,-120.79,-119.13,-120.00),
station_id = c(300,527,300,228,72)
)
在適當的函式之外,很容易做這樣的事情:
out_of_function_test_df <- mini_df %>%
mutate(id = interaction(lat, lon))
這產生了我想要的,即:
lat lon station_id id
1 41.23 -120.79 300 41.23.-120.79
2 37.37 -120.68 527 37.37.-120.68
3 41.23 -120.79 300 41.23.-120.79
4 39.01 -119.13 228 39.01.-119.13
5 32.00 -120.00 72 32.-120
我需要它在用戶指定互動變數的函式中作業。
我已經閱讀了許多堆疊交換帖子,這些帖子解決了類似的問題,但有一些重要的差異。其他問題針對除 mutate 之外的動詞,嘗試應用不同的功能,或者不解決多個用戶指定變數的問題。
閱讀完這些,嘗試了很多東西,并閱讀了這篇文章后,我能想到的最好的方法如下:
create_unique_id <- function(df,
metadata_coords,
unique_id_coords) {
df <- df %>%
mutate_(id = interp(~interaction(args), # causes error with or without tilde
args = c("list", lapply(unique_id_coords, as.name))))
return(df)
}
這會產生一個錯誤:
Error in unique.default(x, nmax = nmax) :
unique() applies only to vectors
這是完整的回溯,如果有幫助的話:
22.
unique.default(x, nmax = nmax)
21.
unique(x, nmax = nmax)
20.
factor(x)
19.
as.factor(args[[i]])
18.
interaction(list("list", lat, lon))
17.
mutate_impl(.data, dots, caller_env())
16.
mutate.tbl_df(tbl_df(.data), ...)
15.
mutate(tbl_df(.data), ...)
14.
as.data.frame(mutate(tbl_df(.data), ...))
13.
mutate.data.frame(.data, !!!dots)
12.
mutate(.data, !!!dots)
11.
mutate_.data.frame(., id = interp(~interaction(args), args = c("list",
lapply(unique_id_coords, as.name))))
10.
mutate_(., id = interp(~interaction(args), args = c("list", lapply(unique_id_coords,
as.name))))
9.
function_list[[k]](value)
8.
withVisible(function_list[[k]](value))
7.
freduce(value, `_function_list`)
6.
`_fseq`(`_lhs`)
5.
eval(quote(`_fseq`(`_lhs`)), env, env)
4.
eval(quote(`_fseq`(`_lhs`)), env, env)
3.
withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
2.
df %>% mutate_(id = interp(~interaction(args), args = c("list",
lapply(unique_id_coords, as.name))))
1.
create_unique_id(df = mini_df, metadata_coords = c("lat", "lon",
"station_id"), unique_id_coords = c("lat", "lon"))
我幾乎沒有足夠的背景知識來幫助我。我很困惑,因為問題似乎在 interact() 函式中很深。interact() 一路呼叫 unique() (這是有道理的),但 unique() 最終失敗了。不知何故,我的函式內對互動()的初始呼叫與在函式外時不同,但我不確定如何。
uj5u.com熱心網友回復:
這個應用程式有tidyr::unite()幫助嗎?
create_unique_id <- function(df,
unique_id_coords) {
df <- df %>%
tidyr::unite("id", {{ unique_id_coords }}, remove = FALSE)
return(df)
}
結果
create_unique_id(mtcars, unique_id_coords = c(wt, qsec)) %>% head()
mpg cyl disp hp drat id wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.62_16.46 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875_17.02 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.32_18.61 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215_19.44 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.44_17.02 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.46_20.22 3.460 20.22 1 0 3 1
uj5u.com熱心網友回復:
這是使用省略號的另一個選項...:
library(rlang)
create_unique_id <- function(df, ...){
df %>%
mutate(id = paste(!!! ensyms(...), sep = "_"))
}
輸出
create_unique_id(mtcars, cyl, hp, vs) %>% head()
mpg cyl disp hp drat wt qsec vs am gear carb id
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 6_110_0
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 6_110_0
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 4_93_1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 6_110_1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 8_175_0
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 6_105_1
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/318528.html
