Присвоение значений глобальной переменной среды с использованием параллельного sapply - PullRequest
0 голосов
/ 17 декабря 2018

Я недавно начал работать с пакетом parallel в R, и он творит чудеса для меня.Тем не менее, я столкнулся с проблемой, для которой я не нашел ответа.

Я пытаюсь переформатировать некоторые данные, и для этого я использую sapply() или parSapply() в параллельном случае.В обычном случае я иду:

sapply(1:nrow(aux),function(x){
  r=which(M$Project==aux$Projecte[x] & M$Product==aux$Producte[x])
  c=which(names(M)==aux$Atribut[x])
  l=aux$meanss[x]
  M[r,c]<<-l
})

Используя <<-, чтобы присвоить значение глобальной среде.В параллельном случае я иду:

no_cores <- detectCores()-2
cl <- makeCluster(no_cores)
clusterExport(cl,c("aux","M"))
parSapply(cl,1:20,function(x){
  r=which(M$Project==aux$Projecte[x] & M$Product==aux$Producte[x])
  c=which(names(M)==aux$Atribut[x])
  l=aux$meanss[x]
  M[r,c]<<-l
})

Я знаю, что значения вычисляются (они печатаются), но они не присваиваются фрейму данных M так же, как с sapply().Я посмотрел вокруг, но не нашел никакой информации по этому поводу.Есть ли какие-то особые соображения, которые я должен рассмотреть, чтобы назначить значения внутри параллельных прикладных функций?Спасибо и, пожалуйста, найдите воспроизводимый пример ниже.

M:

structure(list(Project = c("11I040119", "11I040119", "11I040119", 
"11I040119", "11I040119", "11I040119", "11I040119", "11I040119", 
"11I040119", "11I040119", "11I040119", "11I040119", "11I040119"
), Product = c("Brulerie St. Denis (BOLD)", "Ethical Beans (BOLD)", 
"Folgers (BOLD)", "Illy drip coffe (BOLD)", "Illy Espresso Coffee (BOLD)", 
"Just Us (BOLD)", "Lavazza caffè espresso (BOLD)", "Lavazza Crema e gusto (BOLD)", 
"Lavazza Tierra (BOLD)", "Medaglia d'Oro (BOLD)", "Seattle Best 4 (BOLD)", 
"Starbucks café Verona (BOLD)", "Tully's (BOLD)"), Thing1 = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), Thing2 = c(0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0)), row.names = c(NA, 13L), class = "data.frame")

aux:

structure(list(Projecte = c("11I040119", "11I040119", "11I040119", 
"11I040119", "11I040119", "11I040119", "11I040119", "11I040119", 
"11I040119", "11I040119", "11I040119", "11I040119", "11I040119", 
"11I040119", "11I040119"), Producte = c("Brulerie St. Denis (BOLD)", 
"Ethical Beans (BOLD)", "Folgers (BOLD)", "Illy drip coffe (BOLD)", 
"Illy Espresso Coffee (BOLD)", "Just Us (BOLD)", "Lavazza caffè espresso (BOLD)", 
"Lavazza Crema e gusto (BOLD)", "Lavazza Tierra (BOLD)", "Medaglia d'Oro (BOLD)", 
"Seattle Best 4 (BOLD)", "Starbucks café Verona (BOLD)", "Tully's (BOLD)", 
"Brulerie St. Denis (BOLD)", "Ethical Beans (BOLD)"), Thing = c("Thing1", 
"Thing1", "Thing1", "Thing1", "Thing1", "Thing1", "Thing1", "Thing1", 
"Thing1", "Thing1", "Thing1", "Thing1", "Thing1", "Thing2", "Thing2"
), Value = c(0.142857142857143, 0.242857141154153, 0.614285715988704, 
0, 0, 0.0714285714285714, 1.01428570917674, 0, 0.971428564616612, 
0.5, 0.357142857142857, 0.642857142857143, 0.714285714285714, 
3, 5)), row.names = c(NA, 15L), class = "data.frame")

Желаемый выход (М):

     Project                       Product     Thing1 Thing2
1  11I040119     Brulerie St. Denis (BOLD) 0.14285714      3
2  11I040119          Ethical Beans (BOLD) 0.24285714      5
3  11I040119                Folgers (BOLD) 0.61428572      0
4  11I040119        Illy drip coffe (BOLD) 0.00000000      0
5  11I040119   Illy Espresso Coffee (BOLD) 0.00000000      0
6  11I040119                Just Us (BOLD) 0.07142857      0
7  11I040119 Lavazza caffè espresso (BOLD) 1.01428571      0
8  11I040119  Lavazza Crema e gusto (BOLD) 0.00000000      0
9  11I040119         Lavazza Tierra (BOLD) 0.97142856      0
10 11I040119         Medaglia d'Oro (BOLD) 0.50000000      0
11 11I040119         Seattle Best 4 (BOLD) 0.35714286      0
12 11I040119  Starbucks café Verona (BOLD) 0.64285714      0
13 11I040119                Tully's (BOLD) 0.71428571      0

1 Ответ

0 голосов
/ 17 декабря 2018

Не полное решение, но ради быстроты - распараллеливание работает путем запуска нескольких процессов (представьте себе, что несколько сеансов R выполняются параллельно).Каждый из этих процессов имеет свою собственную глобальную среду .GlobalEnv, поэтому ваш M[r,c] <<- l фактически назначает куда-то еще для каждого процесса.

Одна из возможных реализаций состоит в том, что вы переписываете свою функцию таким образом, что, например, выверните list(r, c, l) и используйте parLapply, и затем у вас будет список индексов и значений, собранных параллельно, и выполните присваивание в основном процессе.

...