Избыточная проблема именования переменных с purrr :: map и dplyr - PullRequest
0 голосов
/ 14 июня 2019

Я полагаю, что это основная проблема, которая вообще не относится к purrr, но застала меня врасплох в этом контексте. Общий ответ был бы хорош, если бы речь не шла о том, как purrr и dplyr играют вместе.

Я пытался назвать переменную, которую я "отображал", так же, как переменную в d.f. Я хотел соответствовать, и это привело к проблемам . Может кто-нибудь объяснить, почему моя первая попытка создать парные различия не удалась?

Это похоже на проблему с изменяемой областью видимости или что-то с избыточными именами, но я не знаю точно, что не так. Очевидно, я нашел обходной путь.

Представьте, что у меня есть данные типа mydf ниже и много переменных, и я хочу вычислить разницу в значениях этих переменных для каждой пары сайтов:

#four sites
site<-rep(c("j", "k", "l", "m"), 3)
#some measurment
val<-1:12
#some variable
vari<-c(rep(1,4), rep(2, 4), rep(3,4))
mydf<-data.frame(site, val, vari)


#compute pairwise differences between values at each site for each variable 
outp<-map_dfr(1:3, function(vari){
    dists<-as.numeric(dist(mydf %>% filter(vari==vari) %>% select(val), method="manhattan"))
    names(dists)<-c("jk","jl", "jm", "kl", "km", "lm" )
    dists
    return(data.frame(t(dists), vari=vari))

})
# looks like there was an issue with using "vari"
outp

#but use a different name for the same variable and it works fine
outp2<-map_dfr(1:3, function(a){
    dists<-as.numeric(dist(mydf %>% filter(vari==a) %>% select(val), method="manhattan"))
    names(dists)<-c("jk","jl", "jm", "kl", "km", "lm" )
    dists
    return(data.frame(t(dists), vari=vari))

})
outp2

edit , как отмечено в комментариях и ответах ниже, проблема здесь заключается в использовании переменной в dplyr::filter, а не в purrr

1 Ответ

1 голос
/ 14 июня 2019

Если вы запускаете какой-то упрощенный код, это может иметь смысл. Например:

# Remove the vector `vari` to avoid confusion.
rm(vari)

# Run using `map` and a simplified function.
map(1:3, function(vari) filter(mydf, vari==vari))

Вышеуказанный вызов map возвращает список из трех кадров данных, каждый из которых идентичен mydf:

[[1]]
   site val vari
1     j   1    1
2     k   2    1
3     l   3    1
4     m   4    1
5     j   5    2
6     k   6    2
7     l   7    2
8     m   8    2
9     j   9    3
10    k  10    3
11    l  11    3
12    m  12    3

[[2]]
   site val vari
1     j   1    1
2     k   2    1
3     l   3    1
4     m   4    1
5     j   5    2
6     k   6    2
7     l   7    2
8     m   8    2
9     j   9    3
10    k  10    3
11    l  11    3
12    m  12    3

[[3]]
   site val vari
1     j   1    1
2     k   2    1
3     l   3    1
4     m   4    1
5     j   5    2
6     k   6    2
7     l   7    2
8     m   8    2
9     j   9    3
10    k  10    3
11    l  11    3
12    m  12    3

Очевидно, что filter(vari == vari) сравнивает mydf$vari с самим собой, что просто возвращает точную копию mydf. Это хорошее поведение, потому что мы всегда знаем, что будет сравнивать filter. Попробуйте то же самое с временной переменной x:

map(1:3, function(x) filter(mydf, vari==x))

, который возвращает ожидаемые подмножества:

[[1]]
  site val vari
1    j   1    1
2    k   2    1
3    l   3    1
4    m   4    1

[[2]]
  site val vari
1    j   5    2
2    k   6    2
3    l   7    2
4    m   8    2

[[3]]
  site val vari
1    j   9    3
2    k  10    3
3    l  11    3
4    m  12    3

Это в основном то, что вы сделали в своем «обходном пути», который я бы назвал допустимым кодом с использованием надлежащих соглашений, то есть вообще не обходным путем.

Аосмит уже указал, что вы можете использовать аккуратную оценку. Это довольно изящно, и у него определенно есть свои варианты использования, но я думаю, что это отразило бы плохую практику в этом конкретном контексте. Использование временной переменной сделает ваш код менее двусмысленным и, следовательно, более читабельным. Это также имеет смысл, поскольку мы действительно имеем дело с двумя разными вещами: vari - это вектор, содержащий (повторяющиеся) значения 1, 2 и 3, в то время как x по сути является временной переменной цикла, равной 1 или 2 или 3, в зависимости от итерации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...