Как создать строки, используя al oop? - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть набор данных, который выглядит следующим образом:

ColA; ColB; ColC;
PAR; BKK; Y;
BKK; SYD; Y;  
NYC; LAX; Y;
LAX; SFO; Y;

Я хочу дублировать строки, где ColC == Y и, если colB строки == colA другой строки, то я хочу создать строка с этими значениями: colA первого и colB второго. В нашем примере это будет выглядеть так:

ColA; ColB; ColC;
PAR; SYD; Y; 
NYC; SFO; Y;

И эти строки будут добавлены в основной набор данных.

Я попытался использовать "для" l oop, и создание временного набора данных для их связывания, но это не работает.

for (i in 1:nrow(maindataset)){
    for (j in (i+1):nrow(maindataset)-1){
        if (maindataset$colB[i]==maindataset$colA[j] & maindataset$colC[i]==maindataset$colC[j]) {
        newDF<-data.frame(ColA=maindataset$colA[i],ColB=maindataset$colA[j],ColC=maindataset$colA[j],stringsAsFactors = FALSE)
    maindataset<-rbind(maindataset,newDF)
}
}
}

Я не уверен, что al oop - лучшее решение. У вас есть идеи, как я могу это решить?

Спасибо!

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Кажется, вы пытались получить newDF, но вы столкнулись с некоторыми трудностями. Вот базовое решение R, которое может быть вам полезно

newDF <- with(subset(df,ColC == "Y"), 
              data.frame(ColA = ColA[na.omit(p <-match(ColA,ColB))],
                         ColB = ColB[which(!is.na(p))],
                         ColC = "Y"))

, такое, что

> newDF
  ColA ColB ColC
1  PAR  SYD    Y
2  NYC  SFO    Y

ДАННЫЕ

df <- structure(list(ColA = c("PAR", "BKK", "NYC", "LAX"), ColB = c("BKK", 
"SYD", "LAX", "SFO"), ColC = c("Y", "Y", "Y", "Y")), class = "data.frame", row.names = c(NA, 
-4L))
1 голос
/ 10 февраля 2020

В общем, когда вам нужно приравнять два столбца в наборе данных, подумайте о выполнении объединения. В этом случае сначала отфильтруйте строки, в которых colB присутствует в colA, затем вы можете выполнить левое соединение с исходным набором данных. Это должно дать вам строки, которые вам нужны. Затем вы можете сделать rbind, чтобы добавить их в исходный набор данных после выбора соответствующих строк и переименования их по мере необходимости:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
set.seed(123)
df <- tibble(colA=sample(state.abb,20,replace = T),
             colB=sample(state.abb,20,replace = T)) %>% 
  filter(colA!=colB)
df # Sample dataframe with two columns having data from same superset
#> # A tibble: 19 x 2
#>    colA  colB 
#>    <chr> <chr>
#>  1 NM    CT   
#>  2 IA    TN   
#>  3 IN    FL   
#>  4 AZ    ME   
#>  5 TN    OK   
#>  6 WY    IN   
#>  7 TX    KY   
#>  8 OR    TX   
#>  9 IN    RI   
#> 10 MO    ID   
#> 11 MT    IA   
#> 12 NE    NY   
#> 13 CA    TN   
#> 14 NE    VT   
#> 15 NV    CT   
#> 16 NH    SD   
#> 17 OH    GA   
#> 18 DE    MN   
#> 19 MT    NE

df1 <- df %>% 
  filter(colB %in% colA) %>% # filter the rows where `colB` is present in `colA`
  left_join(df, by=c('colB'='colA')) # Left join with original dataset
df1
#> # A tibble: 8 x 3
#>   colA  colB  colB.y
#>   <chr> <chr> <chr> 
#> 1 IA    TN    OK    
#> 2 WY    IN    FL    
#> 3 WY    IN    RI    
#> 4 OR    TX    KY    
#> 5 MT    IA    TN    
#> 6 CA    TN    OK    
#> 7 MT    NE    NY    
#> 8 MT    NE    VT

df1 %>% 
  select(-colB) %>% 
  rename(colB=colB.y) $ colB.y is the column you need, so rename it and drop the other one
#> # A tibble: 8 x 2
#>   colA  colB 
#>   <chr> <chr>
#> 1 IA    OK   
#> 2 WY    FL   
#> 3 WY    RI   
#> 4 OR    KY   
#> 5 MT    TN   
#> 6 CA    OK   
#> 7 MT    NY   
#> 8 MT    VT

Создано в 2020-02-10 с помощью Представить пакет (v0.3.0)

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