protected Void doInBackground(Integer... params)
{
onProgessUpdate("Contacting server..Please wait..");
...
}
Urrrm, нет, это не сработает.
Попробуйте ...
publishProgress("Contacting server..Please wait..");
Вы должны «опубликовать» свой прогресс в doInBackground(..)
в порядок для onProgressUpdate(...)
, который будет вызываться.
Также не вызывайте dialog.dismiss()
в doInBackground(...)
вместо этого в onPostExecute(...)
.
Другой вопрос, заданный специально , как выполнить несколько левых объединений, используя dplyr в R . Вопрос был помечен как дубликат этого, поэтому я отвечу здесь, используя три примера данных:
library(dplyr)
x <- data_frame(i = c("a","b","c"), j = 1:3)
y <- data_frame(i = c("b","c","d"), k = 4:6)
z <- data_frame(i = c("c","d","a"), l = 7:9)
Обновление июня 2018 года: я разделил ответ в трех разделах, представляющих три разных способа выполнения слияние. Вероятно, вы захотите использовать путь purrr
, если вы уже используете пакеты tidyverse. Для сравнения ниже вы найдете базовую версию R с использованием того же набора данных образца.
reduce
из пакета purrr
Пакет purrr
предоставляет функцию reduce
, которая имеет сжатый синтаксис:
library(tidyverse)
list(x, y, z) %>% reduce(left_join, by = "i")
# A tibble: 3 x 4
# i j k l
# <chr> <int> <int> <int>
# 1 a 1 NA 9
# 2 b 2 4 NA
# 3 c 3 5 7
Вы также можете выполнять другие объединения, такие как full_join
или inner_join
:
list(x, y, z) %>% reduce(full_join, by = "i")
# A tibble: 4 x 4
# i j k l
# <chr> <int> <int> <int>
# 1 a 1 NA 9
# 2 b 2 4 NA
# 3 c 3 5 7
# 4 d NA 6 8
list(x, y, z) %>% reduce(inner_join, by = "i")
# A tibble: 1 x 4
# i j k l
# <chr> <int> <int> <int>
# 1 c 3 5 7
dplyr::left_join()
с базой R Reduce()
list(x,y,z) %>%
Reduce(function(dtf1,dtf2) left_join(dtf1,dtf2,by="i"), .)
# i j k l
#1 a 1 NA 9
#2 b 2 4 NA
#3 c 3 5 7
merge()
с базой R Reduce()
И для целей сравнения здесь представлена базовая R-версия left join
Reduce(function(dtf1, dtf2) merge(dtf1, dtf2, by = "i", all.x = TRUE),
list(x,y,z))
# i j k l
# 1 a 1 NA 9
# 2 b 2 4 NA
# 3 c 3 5 7
Более новое решение может быть доступно в пакете purrr
. Для вашего точного вопроса вы можете использовать reduce()
отметить малый r по сравнению с base::Reduce
, но вы могли бы полностью устранить проблему, используя map_dfr()
или map_dfc
, которые могли бы предотвратить проблему, сделав карту и уменьшить шаг в одном.
Я буду повторно использовать пример данных из @PaulRougieux
x <- data_frame(i = c("a","b","c"), j = 1:3)
y <- data_frame(i = c("b","c","d"), k = 4:6)
z <- data_frame(i = c("c","d","a"), l = 7:9)
Вот короткое и сладкое решение, использующее purrr
и tidyr
library(tidyverse)
list(x, y, z) %>%
map_df(gather, key=key, value=value, -i) %>%
spread(key, value)
Вы можете использовать рекурсию для этого. Я не проверял следующее, но он должен дать вам правильную идею:
MergeListOfDf = function( data , ... )
{
if ( length( data ) == 2 )
{
return( merge( data[[ 1 ]] , data[[ 2 ]] , ... ) )
}
return( merge( MergeListOfDf( data[ -1 ] , ... ) , data[[ 1 ]] , ... ) )
}
Вы можете сделать это, используя merge_all
в пакете reshape
. Вы можете передать параметры merge
с помощью аргумента ...
reshape::merge_all(list_of_dataframes, ...)
. Это отличный ресурс для разных методов для объединения кадров данных .
Уменьшить делает это довольно легко:
merged.data.frame = Reduce(function(...) merge(..., all=T), list.of.data.frames)
Вот полный пример с использованием некоторых макетных данных:
set.seed(1)
list.of.data.frames = list(data.frame(x=1:10, a=1:10), data.frame(x=5:14, b=11:20), data.frame(x=sample(20, 10), y=runif(10)))
merged.data.frame = Reduce(function(...) merge(..., all=T), list.of.data.frames)
tail(merged.data.frame)
# x a b y
#12 12 NA 18 NA
#13 13 NA 19 NA
#14 14 NA 20 0.4976992
#15 15 NA NA 0.7176185
#16 16 NA NA 0.3841037
#17 19 NA NA 0.3800352
И вот пример использования этих данных для репликации my.list
:
merged.data.frame = Reduce(function(...) merge(..., by=match.by, all=T), my.list)
merged.data.frame[, 1:12]
# matchname party st district chamber senate1993 name.x v2.x v3.x v4.x senate1994 name.y
#1 ALGIERE 200 RI 026 S NA <NA> NA NA NA NA <NA>
#2 ALVES 100 RI 019 S NA <NA> NA NA NA NA <NA>
#3 BADEAU 100 RI 032 S NA <NA> NA NA NA NA <NA>
Примечание: похоже, что это, возможно, ошибка в merge
. Проблема в том, что нет никакой проверки того, что добавление суффиксов (для обработки перекрывающихся имен несоответствий) фактически делает их уникальными. В какой-то момент он использует [.data.frame
, который делает make.unique
имена, в результате чего rbind
терпит неудачу.
# first merge will end up with 'name.x' & 'name.y'
merge(my.list[[1]], my.list[[2]], by=match.by, all=T)
# [1] matchname party st district chamber senate1993 name.x
# [8] votes.year.x senate1994 name.y votes.year.y
#<0 rows> (or 0-length row.names)
# as there is no clash, we retain 'name.x' & 'name.y' and get 'name' again
merge(merge(my.list[[1]], my.list[[2]], by=match.by, all=T), my.list[[3]], by=match.by, all=T)
# [1] matchname party st district chamber senate1993 name.x
# [8] votes.year.x senate1994 name.y votes.year.y senate1995 name votes.year
#<0 rows> (or 0-length row.names)
# the next merge will fail as 'name' will get renamed to a pre-existing field.
Самый простой способ исправить - это не оставить поле для переименования для полей дубликатов (которых здесь много) до merge
. Например:
my.list2 = Map(function(x, i) setNames(x, ifelse(names(x) %in% match.by,
names(x), sprintf('%s.%d', names(x), i))), my.list, seq_along(my.list))
merge
/ Reduce
будет работать нормально.
empty <- data.frame(x=numeric(0),a=numeric(0); L3 <- c(empty,empty,list.of.data.frames,empty,empty,empty)
и получил некоторые странные вещи, которые я еще не понял.
– Ben Bolker
15 November 2011 в 00:10
map_dfr()
илиmap_dfc()
– DaveRGP 30 June 2017 в 08:42