ggplot в инструкции ifelse печатает список данных вместо графика [duplicate]

.NET Framework или PowerShell не имеют явной поддержки для рекурсивных операций с файлами (включая загрузку). Вы должны реализовать рекурсию самостоятельно:

  • Список удаленных каталогов
  • Итерировать записи, загружать файлы и рекурсировать в поддиректории (перечисляя их снова и т. Д.).

Трудная часть состоит в том, чтобы идентифицировать файлы из подкаталогов. Невозможно сделать это переносимым образом с платформой .NET (FtpWebRequest или WebClient). К сожалению, платформа .NET не поддерживает команду MLSD, которая является единственным переносимым способом получения списка каталогов с атрибутами файлов в протоколе FTP. См. Также Проверка, является ли объект на FTP-сервере файлом или каталогом .

Ваши параметры:

  • Выполняет операцию над именем файла, которое наверняка сбой для файла и успех для каталогов (или наоборот). То есть вы можете попробовать загрузить «имя». Если это удастся, это файл, если это не удается, это каталог.
  • Возможно, вам повезло, и в вашем конкретном случае вы можете указать файл из каталога по имени файла (то есть все ваши файлы имеют расширение, в то время как в подкаталогах нет)
  • Вы используете длинный список каталогов (метод LIST command = ListDirectoryDetails) и пытаетесь разобрать листинг на сервере. Многие FTP-серверы используют список * nix-style, в котором вы идентифицируете каталог по d в самом начале записи. Но многие серверы используют другой формат. В следующем примере используется этот подход (при условии, что формат * nix)
function DownloadFtpDirectory($url, $credentials, $localPath)
{
    $listRequest = [Net.WebRequest]::Create($url)
    $listRequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
    $listRequest.Credentials = $credentials

    $lines = New-Object System.Collections.ArrayList

    $listResponse = $listRequest.GetResponse()
    $listStream = $listResponse.GetResponseStream()
    $listReader = New-Object System.IO.StreamReader($listStream)
    while (!$listReader.EndOfStream)
    {
        $line = $listReader.ReadLine()
        $lines.Add($line) | Out-Null
    }
    $listReader.Dispose()
    $listStream.Dispose()
    $listResponse.Dispose()

    foreach ($line in $lines)
    {
        $tokens = $line.Split(" ", 9, [StringSplitOptions]::RemoveEmptyEntries)
        $name = $tokens[8]
        $permissions = $tokens[0]

        $localFilePath = Join-Path $localPath $name
        $fileUrl = ($url + $name)

        if ($permissions[0] -eq 'd')
        {
            if (!(Test-Path $localFilePath -PathType container))
            {
                Write-Host "Creating directory $localFilePath"
                New-Item $localFilePath -Type directory | Out-Null
            }

            DownloadFtpDirectory ($fileUrl + "/") $credentials $localFilePath
        }
        else
        {
            Write-Host "Downloading $fileUrl to $localFilePath"

            $downloadRequest = [Net.WebRequest]::Create($fileUrl)
            $downloadRequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
            $downloadRequest.Credentials = $credentials

            $downloadResponse = $downloadRequest.GetResponse()
            $sourceStream = $downloadResponse.GetResponseStream()
            $targetStream = [System.IO.File]::Create($localFilePath)
            $buffer = New-Object byte[] 10240
            while (($read = $sourceStream.Read($buffer, 0, $buffer.Length)) -gt 0)
            {
                $targetStream.Write($buffer, 0, $read);
            }
            $targetStream.Dispose()
            $sourceStream.Dispose()
            $downloadResponse.Dispose()
        }
    }
}

Используйте следующую функцию:

$credentials = New-Object System.Net.NetworkCredential("user", "mypassword") 
$url = "ftp://ftp.example.com/directory/to/download/"
DownloadFtpDirectory $url $credentials "C:\target\directory"

Код переводится с моего примера на C # в C # Загрузите все файлы и подкаталоги через FTP .


Если вы хотите избежать проблем с разбором форматов списков каталогов для конкретного сервера, используйте стороннюю библиотеку, которая поддерживает команда MLSD и / или разбор различных форматов листинга LIST; и рекурсивные загрузки.

Например, с помощью WinSCP .NET assembly вы можете загрузить целую директорию с помощью одного вызова Session.GetFiles :

# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "ftp.example.com"
    UserName = "user"
    Password = "mypassword"
}

$session = New-Object WinSCP.Session

try
{
    # Connect
    $session.Open($sessionOptions)

    # Download files
    $session.GetFiles("/directory/to/download/*", "C:\target\directory\*").Check()
}
finally
{
    # Disconnect, clean up
    $session.Dispose()
}    

Внутри WinSCP использует команду MLSD, если она поддерживается сервером.

Метод Session.GetFiles по умолчанию рекурсивный.

(я автор WinSCP)

11
задан Blue Magister 31 January 2013 в 21:12
поделиться

3 ответа

if ( cond) { yes } else { no } является структурой управления. Он был разработан для создания программных вилок, а не для обработки последовательности. Я думаю, что многие люди пришли из SPSS или SAS, авторы которых выбрали «IF» для реализации условного присвоения в своих функциях DATA или TRANSFORM, и поэтому они ожидают, что R будет вести себя одинаково, тогда как R - из традиции программирования. R неявные for-loops встроены во множество векторизованных функций (включая ifelse).

ifelse принимает выражение, которое строит вектор логических значений в качестве первого аргумента. Второй и третий аргументы должны быть векторами равной длины, и либо первый из них, либо второй выбирается. Это похоже на команды SPSS / SAS IF, которые имеют неявный режим работы по строке.

12
ответ дан 42- 26 August 2018 в 10:17
поделиться

Из документации ifelse:

 ‘ifelse’ returns a value with the same shape as ‘test’ which is
 filled with elements selected from either ‘yes’ or ‘no’ depending
 on whether the element of ‘test’ is ‘TRUE’ or ‘FALSE’.

Таким образом, ваш вход имеет длину один, поэтому выход усечен до длины 1.

Вы также можете увидеть это проиллюстрировано более простым пример:

ifelse(TRUE, c(1, 3), 7)
# [1] 1
13
ответ дан Dason 26 August 2018 в 10:17
поделиться

По какой-то причине это помечено как дубликат . Почему ifelse () возвращает однозначный вывод?

Итак, работа для этого вопроса:

a=3
yo <- ifelse(a==1, 1, list(c(1,2)))
yo[[1]]
0
ответ дан Ram B 26 August 2018 в 10:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: